相機幀訪問(實驗性)

相機幀訪問示例


警告!

相機幀訪問功能被标記爲實驗性,因爲它目前不完全支持所有公共 AR Foundation API,并且由于包和(hé) Snapdragon Spaces 服務端的(de)優化(huà),版本之間的(de)向後兼容性可(kě)能會受到影(yǐng)響。


這(zhè)個(gè)示例演示了(le)如何獲取 RGB 相機幀和(hé)内部屬性用(yòng)于圖像處理(lǐ)。有關相機幀訪問的(de)基本信息及 AR Foundation 的(de) AR Camera Manager 組件的(de)功能,請參閱 Unity 文檔。要使用(yòng)此功能,需要在 OpenXR 插件設置中啓用(yòng)它,路徑爲:項目設置 > XR 插件管理(lǐ) > OpenXR(> Android 标簽)。

 

示例工作原理(lǐ)

将 AR Camera Manager 組件添加到 AR Session Origin > AR Camera 遊戲對(duì)象中,将啓用(yòng)相機訪問子系統。啓動時(shí),子系統會從設備中檢索有效的(de)傳感器配置。如果找到有效的(de) Y'UV420sp 或 YUY2 傳感器配置,子系統将選擇該配置作爲 CPU 相機圖像的(de)提供者。從概念上講,AR Camera Manager 代表一個(gè)單一的(de)相機,不能同時(shí)管理(lǐ)多(duō)個(gè)傳感器。

 

示例場(chǎng)景包含兩個(gè)面闆:

● 一個(gè)相機視頻(pín)面闆,顯示來(lái)自設備相機的(de)最新 CPU 圖像,并帶有暫停和(hé)恢複按鈕。

● 一個(gè)相機信息面闆,列出設備相機的(de)各種屬性。

 

圖片9.png

 

獲取 CPU 圖像

每當子系統獲得(de)新的(de)相機幀時(shí),AR Camera Manager 将觸發 frameReceived 事件。訂閱此事件可(kě)以讓其他(tā)腳本盡早獲取最新的(de)相機幀并對(duì)其進行處理(lǐ)。一旦相機幀可(kě)用(yòng),Camera Manager 的(de) TryAcquireLatestCpuImage 函數将返回一個(gè) XRCpuImage 對(duì)象,這(zhè)個(gè)對(duì)象代表來(lái)自選定設備相機的(de)單張原始圖像。可(kě)以使用(yòng) XRCpuImage 的(de) Convert 函數提取該圖像的(de)原始像素數據,Convert 函數會返回一個(gè) NativeArray<byte>。Snapdragon Spaces 不支持通(tōng)過 XRCpuImage.ConvertAsync 進行異步圖像轉換。

 

 圖片10.png

 

有關如何使用(yòng) frameReceived、TryAcquireLatestCpuImage 和(hé) XRCpuImage 的(de)詳細信息,請參閱 Unity 文檔

 

警告!

根據所使用(yòng)的(de)設備,相機幀訪問可(kě)能需要幾秒鐘(zhōng)才能初始化(huà)。在子系統成功初始化(huà)之前,請不要嘗試訪問幀。強烈建議(yì)使用(yòng) AR Foundation API 的(de) frameReceived 事件,以避免出現錯誤。


以下(xià)示例代碼在觸發 frameReceived 事件時(shí),從 AR Camera Manager 請求 CPU 圖像。如果成功,它将直接将 XRCpuImage 的(de)原始像素數據提取到托管的(de) Texture2D 的(de) GetRawTextureData<byte> 緩沖區(qū)中,并使用(yòng) Apply 方法應用(yòng)紋理(lǐ)緩沖區(qū)。最後,它會更新目标 RawImage 中的(de)紋理(lǐ),使新幀在應用(yòng)程序的(de) UI 中可(kě)見。

 

圖片11.png

 

以下(xià)是 AR Camera Manager 支持的(de)紋理(lǐ)格式:

● RGB24

● RGBA32

● BGRA32

 

檢索 YUV 平面數據

Snapdragon Spaces 目前支持 Y′UV420sp 和(hé) YUY2 格式。Y′UV420sp 包含一個(gè) Y 緩沖區(qū),後跟交錯的(de) 2x2 子采樣 U/V 緩沖區(qū)。YUY2 包含一個(gè)單一的(de)緩沖區(qū),其中交錯了(le) Y 和(hé) U/V 樣本,每個(gè)樣本以 Y-U-Y-V 的(de)形式表示,代表兩個(gè)水(shuǐ)平像素的(de)色度信息,沒有垂直子采樣。有關 YUV 顔色模型的(de)詳細信息,請參閱 YCbCr 維基百科文章(zhāng)中的(de) YUV 部分(fēn)。

 

如果不需要 RGB 轉換,可(kě)以通(tōng)過 XRCpuImage 的(de) GetPlane 方法檢索原始 YUV 平面數據。此方法返回一個(gè) XRCpuImage.Plane 對(duì)象,可(kě)以從中讀取平面數據。通(tōng)過 XRCpuImage.planeCount 可(kě)以區(qū)分(fēn)格式,該屬性指示表示幀的(de)平面數量。

 

Y'UV420sp

 

● Y 平面數據的(de)索引爲 0,可(kě)以通(tōng)過 GetPlane(0) 訪問。

● UV 平面數據的(de)索引爲 1,可(kě)以通(tōng)過 GetPlane(1) 訪問。


YUY2

YUYV 平面數據的(de)索引爲 0,可(kě)以通(tōng)過 GetPlane(0) 訪問。

 

圖片12.png

 

有關 XRCpuImage.GetPlane 的(de)詳細信息,請參閱 Unity 文檔

 

有關 XRCpuImage.Plane 的(de)詳細信息,請參閱 Unity 文檔。


以下(xià)示例代碼在 frameReceived 事件觸發時(shí)請求來(lái)自 AR Camera Manager 的(de) CPU 圖像,如果成功,它會獲取 XRCpuImage 的(de)原始平面數據,并根據 YUV 格式應用(yòng)不同的(de)圖像處理(lǐ)算(suàn)法。

 

圖片13.png

 

檢索傳感器/内部信息

攝像頭管理(lǐ)器的(de) TryGetIntrinsics 函數将返回一個(gè) XRCameraIntrinsics 對(duì)象,該對(duì)象描述了(le)所選傳感器的(de)物(wù)理(lǐ)特性。有關 XRCameraIntrinsics 的(de)詳細信息,請參閱 Unity 文檔。(https://docs.unity3d.com/Packages/com.unity.xr.arsubsystems@4.2/api/UnityEngine.XR.ARSubsystems.XRCameraIntrinsics.html)

以下(xià)示例代碼檢索所選傳感器的(de)内參,并在應用(yòng)程序 UI 中顯示這(zhè)些信息。

 

圖片14.png


檢索傳感器/外部參數

AR Foundation API 不提供傳感器的(de)外參,不過,您可(kě)以使用(yòng)以下(xià)兩種方法來(lái)獲取傳感器的(de)外參:

 

方法 1:Snapdragon Spaces 輸入綁定

Snapdragon Spaces 提供了(le) ColorCameraPosition 和(hé) ColorCameraRotation 的(de)輸入動作。您可(kě)以将這(zhè)些輸入動作與 Tracked Pose Driver (Input System) 配合使用(yòng),通(tōng)過将它們綁定到 Position Input 和(hé) Rotation Input 上。将 Tracked Pose Driver (Input System) 組件添加到一個(gè) GameObject 上,該 GameObject 的(de)位姿将與彩色攝像頭的(de)外參位姿匹配。

 

 圖片15.png

 

下(xià)圖展示了(le)如何使用(yòng)這(zhè)些輸入綁定。

 

圖片16.png


方法二:Snapdragon Spaces 相機姿态提供器

Space相機姿态提供器組件添加到場(chǎng)景中,并使用(yòng) GetPoseFromProvider 函數來(lái)獲取與 AR 相機管理(lǐ)器最新的(de) frameReceived 事件相關的(de)相機姿态。這(zhè)個(gè)姿态是相對(duì)于 AR 會話(huà)坐(zuò)标系統的(de)。

 

下(xià)面的(de)示例代碼演示了(le)如何獲取所選傳感器的(de)外參并在應用(yòng)程序的(de) UI 中顯示。

 

圖片17.png


Spaces Camera Pose Provider還(hái)可(kě)以用(yòng)作Tracked Pose Driver的(de)姿勢提供程序。

 

提升性能的(de)提示:

相機訪問操作可(kě)能會消耗較多(duō)計算(suàn)資源,無論是由于圖像分(fēn)辨率較大(dà)還(hái)是算(suàn)法的(de)複雜(zá)性。

● 使用(yòng) XRCpuImage.Convert 轉換圖像時(shí),提供較小的(de) outputDimensions 以減少計算(suàn)量。

● 使用(yòng) XRCpuImage.GetPlane 處理(lǐ)圖像時(shí),可(kě)以考慮對(duì)數據緩沖區(qū)進行下(xià)采樣。

 

Snapdragon Spaces 提供了(le)直接内存訪問轉換設置,這(zhè)改變了(le) XRCpuImage.Convert 讀取和(hé)寫入數據的(de)方式。默認情況下(xià),Snapdragon Spaces 使用(yòng) Marshal.Copy 進行幀數據的(de)移動。啓用(yòng)此設置後,Spaces 将使用(yòng) NativeArray<byte> 直接表示源和(hé)目标緩沖區(qū)。可(kě)以在 Project Settings > XR Plug-in Management > OpenXR (> Android Tab) > Snapdragon Spaces > Camera Frame Access (Experimental) > Direct Memory Access Conversion 中找到這(zhè)個(gè)設置。啓用(yòng)此設置可(kě)能會在某些設備上提高(gāo)性能,但在其他(tā)架構上的(de)表現可(kě)能會有所下(xià)降。以下(xià)是建議(yì)啓用(yòng)直接内存訪問轉換設置的(de)設備表:


設備

建議(yì)

Lenovo ThinkReality A3

性能提升,推薦使用(yòng)

Lenovo ThinkReality VRX

性能不足,不推薦使用(yòng)

 

Spaces AR C相機管理(lǐ)器配置和(hé) DownsamplingStride 屬性在版本 0.21.0 中已被棄用(yòng)。請改用(yòng) XRCpuImage.ConversionParams 設置較小的(de) outputDimensions,或者使用(yòng) XRCpuImage.GetPlane 并設置自定義下(xià)采樣因子。

 

檢索其他(tā)的(de)傳感器數據

Spaces AR Camera Manager Config 可(kě)以通(tōng)過 GetActiveCameraCount 方法獲取設備中的(de)相機傳感器數量。這(zhè)些信息對(duì)于區(qū)分(fēn)雙鏡頭設備和(hé) VR 設備,以及正确處理(lǐ)相機圖像可(kě)能非常重要。