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

Raw Depth API 可為相機影像提供深度資料,其準確率高於「Full Depth API」(完整的深度 API 資料),但不一定能涵蓋每個像素。我們還可進一步處理原始深度圖片及相應的可信度圖片,讓應用程式只使用準確符合其個別用途的深度資料。

裝置相容性

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

原始深度 API 與完整的深度 API

使用 Raw Depth API 可提高深度估算的準確度,但原始深度圖像可能不包含相機影像中所有像素的深度預估。相較之下,完整的深度 API 為每個像素提供預估深度,但每個像素深度資料可能會因為深度估計和內插值而較不準確。這兩種 API 的深度圖片格式和大小皆相同。只有內容不同。

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

API 傳回 相機圖片 厚度圖片 「信心」圖片
原始深度 API
  • 原始的深度圖片,內含非常精確的相機圖像中某些像素 (但並非全部) 的深度預估。
  • 能使每個原始深度圖片像素充滿信心的信心圖片。沒有深度預估的相機圖片像素信賴值為零。
深度 API
  • 一個「順暢」包含每個像素的深度預估。
  • 這個 API 未提供可信度圖片。

圖片可信度

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

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

運算費用

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

用途

使用 Raw Depth 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;
}