在 AR Foundation Android 应用中使用“原始深度”功能

Raw Depth API 为相机图像提供深度数据,其准确性比完整 Depth API 数据高,但不一定能覆盖每个像素。原始深度图像及其匹配的置信度图像也可以进一步处理,让应用仅使用准确度足够高的深度数据来满足具体用例的要求。

设备兼容性

原始深度数据可在所有支持 Depth API 的设备上使用。与完整的 Depth API 一样,原始 Depth API 不需要受支持的硬件深度传感器,例如飞行时间 (ToF) 传感器。不过,Raw Depth API 和完整 Depth API 均可利用设备可能具备的任何受支持硬件传感器。

原始深度 API 与完整深度 API

Raw Depth API 提供准确度更高的深度估计值,但原始深度图像可能不包含相机图像中所有像素的深度估计值。相比之下,Full Depth API 为每个像素提供估算的深度,但由于深度估算值的平滑和插值,每像素的深度数据可能不太准确。两个 API 中的深度图像格式和大小相同。只有内容不同。

下表使用厨房中的椅子和桌子的图片说明了 Raw Depth API 与完整 Depth API 之间的区别。

API 返回 相机图像 深度图片 置信度图片
原始深度 API
  • 原始深度图像,包含相机图像中部分(而非全部)像素的非常准确的深度估算值。
  • 为每个原始深度图像像素提供置信度的置信度图像。没有深度估算的相机图片像素置信度为 0。
全深度 API
  • 一个“平滑”包含每个像素深度估算值的深度图像。
  • 此 API 未提供任何置信度图片。
不适用

置信度图片

在 Raw Depth API 返回的置信度图像中,颜色较浅的像素具有较高的置信度值,白色像素表示完整的置信度,黑色像素表示没有置信度。一般来说,相机图像中纹理多的区域(例如树木)要比纹理不多的区域(例如空白墙)具有更高的原始深度置信度。没有纹理的表面产生的置信度通常为零。

如果目标设备具有受支持的硬件深度传感器,那么图片中距离相机足够近的区域的置信度可能会提高,即使在无纹理的表面上也是如此。

计算费用

Raw Depth API 的计算费用大约是完整 Depth API 计算费用的一半。

使用场景

借助原始深度 API,您可以获取深度图像,从而更详细地呈现场景中对象的几何图形。在打造 AR 体验时,原始深度数据非常有用,在这些体验中,几何图形理解任务需要更高的深度准确性和细节。一些用例包括:

  • 3D 重建
  • 效果衡量
  • 形状检测

前提条件

确保您了解 AR 基础概念 以及如何在继续之前配置 ARCore 现场录像

启用景深数据

新的 ARCore 会话中,检查用户的设备是否支持深度。由于处理能力限制,并非所有与 ARCore 兼容的设备都支持 Depth API。为节省资源,ARCore 默认停用深度。启用深度模式,让应用使用 Depth API。

var occlusionManager = // Typically acquired from the Camera game object.

// Check whether the user's device supports the Depth API.
if (occlusionManager.descriptor?.supportsEnvironmentDepthImage)
{
    // If depth mode is available on the user's device, perform
    // the steps you want here.
}

获取最新的原始深度图像

调用 AROcclusionManager.TryAcquireEnvironmentDepthCpuImage() 并使用 AROcclusionManager.environmentDepthTemporalSmoothingRequested 获取 CPU 上最新的原始深度图像。

获取最新的原始深度置信度图片

调用 AROcclusionManager.TryAcquireEnvironmentDepthConfidenceCpuImage() 并使用 AROcclusionManager.environmentDepthTemporalSmoothingRequested 获取 CPU 上的置信度图片。

// Attempt to get the latest environment depth image.
if (occlusionManager && occlusionManager.TryAcquireEnvironmentDepthConfidenceCpuImage(out XRCpuImage image))
{
    using (image)
    {
        UpdateRawImage(m_RawEnvironmentDepthConfidenceImage, image);
    }
}
else
{
    m_RawEnvironmentDepthConfidenceImage.enabled = false;
}