在 AR 基金會 Android 應用程式中使用原始深度

Raw Depth API 會為相機圖片提供深度資料,其準確度高於完整 Depth API 資料,但不一定涵蓋每個像素。原始深度圖片和相符的信心圖片也可以進一步處理,讓應用程式只使用深度資料,以便在個別用途中達到足夠的準確度。

裝置相容性

所有支援 Depth API 的裝置皆可使用原始深度。Raw Depth API 和完整 Depth API 一樣,不需要支援的硬體深度感應器,例如飛行時間 (ToF) 感應器。不過,Raw Depth API 和完整 Depth API 都會使用裝置可能具備的任何支援硬體感應器。

原始深度 API 與完整深度 API

Raw Depth API 可提供更精確的深度估計值,但原始深度圖片可能不會包含相機圖片中所有像素的深度估計值。相較之下,完整的 Depth API 會為每個像素提供預估深度,但由於深度預估值會經過平滑處理和內插,因此每個像素的深度資料可能較不準確。兩個 API 的深度圖格式和大小相同。只有內容不同。

下表以廚房椅子和一張桌子的圖片,說明 Raw Depth API 與完整 Depth API 之間的差異。

API 傳回 相機圖像 深度圖像 可信度圖片
原始深度 API
  • 原始深度圖像,其中包含相機圖像中部分 (但非全部) 像素的深度估計值。
  • 能使每個原始深度圖片像素充滿信心的信心圖片。相機圖像像素如果沒有深度估計值,其信心值為零。
完整深度 API
  • 單一「平滑」深度圖片,其中包含每個像素的深度估計值。
  • 這個 API 不會提供信心圖片。

信心圖片

在 Raw Depth API 傳回的信心圖片中,光線較淺的像素有較高的可信度值,白色的像素代表完全信心,黑色的像素則代表沒有信心。一般而言,相機圖像中紋理較高的區域 (例如樹木) 擁有較高的原始深度可信度,遠地高於不含空白牆面等區域。沒有紋理的表面通常會產生零信心。

如果目標裝置具備支援的硬體深度感應器,即使在無紋理的表面上,圖片中靠近相機區域的可信度也可能會比較高。

運算費用

Raw Depth API 的運算成本約為完整 Depth API 的半數。

用途

您可以使用 Raw Depth API 取得深度圖片,以便更詳細地呈現場景中物件的幾何圖形。如要打造 AR 體驗,原始深度資料就相當實用,因為此時必須提高深度準確度和細節,才能處理幾何圖形理解工作。某些用途包括:

  • 3D 重建
  • 評估
  • 形狀偵測

必要條件

請務必先瞭解基本 AR 概念,以及如何設定 ARCore 工作階段,再繼續操作。

啟用深度

新的 ARCore 工作階段中,確認使用者的裝置是否支援 Depth。由於處理效能受限,並非所有 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;
}