網易戲精ARCore短視頻新玩法實踐

《網易戲精》是網易人工智能事業部旗下一款AI短視頻產品,用戶可以隨手拍出自己的特效視頻,其中包含數十個有趣的奇幻道具,其中放置類的道具只需要掃一下平面,即可擺放進現實世界中進行互動,既有充滿霓虹燈的旺角街頭、會隨音樂抖動的DJ打碟臺、迪廳球,也有煙霧繚繞的迷幻場景等等。

(會隨音樂抖動的DJ打碟臺)

此類放置類道具在安卓端基於Google的ARCore技術實現。本文整理歸納項目研發中ARCore的使用及研發歷程,與大家一起分享在AR應用開發中遇到的問題及實踐。主要分爲以下幾個方面,已有相關經驗的ARCore開發者可以選擇性跳過。

  1. ARCore簡述
  2. ARCore原理的進一步理解
  3. ARCore和ARKit的功能性對比
  4. ARCore API架構梳理
  5. ARCore的兼容性及解決方案
  6. 開發者可能會遇到的Troubleshoot

ARCore簡述

ARCore SDK主要由三大模塊構成:運動跟蹤、環境理解、光照估計。

  1. 運動跟蹤可以讓手機理解和跟蹤它相對於現實世界的位置。
  2. 環境理解讓手機可以檢測各類表面(例如地面、咖啡桌或牆壁等水平、垂直表面)的大小和位置。
  3. 光估計讓手機可以估測環境當前的光照條件。

ARCore原理的進一步理解

對ARCore底層原理的瞭解可以幫助我們瞭解計算的過程以及解決一些問題。

首先,ARCore使用視覺慣性測距系統(Visual Inertial Odometry,簡稱 VIO)的算法來實現運動跟蹤。VIO將從設備的攝像機中識別圖像特徵與內部運動傳感器結合起來,以獲得設備的6DOF(6 Degree Of Freedom,6度自由度)信息。我們常說的6DOF指的是三維的位置與三維的旋轉,而3DOF常指三維的旋轉(直接通過陀螺儀即可獲得,比起6DOF計算較爲簡單)。


  (上圖即是6DoF的圖示)

慣性測量單元(Inertial measurement unit,簡稱 IMU)的讀數大約爲1000次每秒並且是基於加速度的(用戶的移動)。航跡推算法(Dead Reckoning)用於測量 IMU 讀數之間的設備移動,但這種方法推算是一種估算,就像如果我讓你向前走一步,然後猜測走了多遠一樣,此時會用航跡推算法來估計距離。但慣導系統中的誤差會隨時間累積,所以 IMU 幀率越長,慣導系統從視覺系統中復位後的時間越長,追蹤位置距離真實位置偏差就越多。

視覺/光學測量使用的是攝像機來採集視覺信息,設備幀率通常爲 30fps 並且依賴距離(不同的場景幀率也有所不同)。光學系統通常隨着距離的增大誤差也不斷的增大(時間也會有輕度影響),所以用戶運動得越遠,誤差就越大。

慣性導航系統與視覺測量系統各有各的優勢和不足。並且視覺和慣性跟蹤系統是基於完全不同的測量系統,他們之間並沒有相互依賴,所以他們整合在一起可以互相彌補缺陷。這意味着可以蓋住攝像機或者只看到一個具有很少光學特徵的場景(比如白牆),而慣性系統照樣可以正常工作,或者設備在完全靜止的條件下,視覺系統可以呈現出一個比慣性系統更加穩定的姿態。在此之上這個算法使用卡爾曼濾波器不斷地選擇最佳姿態,從而實現穩定跟蹤。

與ARKit的功能上的對比

爲了儘可能保證Android用戶和iOS用戶的功能一致性,我們整理了ARKit和ARCore在各個版本上的功能。版本上需要注意的是,ARKit的版本取決與手機的操作系統級別,ARCore的運行版本取決於手機上安裝的ARCore Runtime Apk,Runtime對SDK採取向下兼容機制,並且用戶如首次安裝ARCore Runtime Apk後,之後作爲內核服務自動更新。

ARKit ARCore
6DOF追蹤 支持(1.0)(iOS11) 支持(1.0)
相機分辨率、自動對焦 支持(1.5)(iOS11.3) 支持(1.4)
圖片掃描 支持(1.5)(iOS11.3) 支持(1.2)
雲錨點 支持(2.0)(iOS12) 支持(1.2)

ARCore API架構梳理

ARCore SDK模塊設計易於理解,開發者可以很簡單地找到相應的API,簡單列了一張重要/常用API的對應概念:

Session: 負責整個AR算法的生命週期和算法配置文件選項,主要有Start\Pause\Resume\Stop,配置文件可配置是否開啓位置追蹤、2D圖片識別、環境光檢測等功能,多餘的配置涉及到可觀的性能開銷,並且在切換配置的過程中會涉及到相機畫面的重啓,建議產品根據各自情況進行選擇。

運動追蹤相關

Frame.CameraImage.Texture Frame.CameraImage.DisplayUvCoords 相機紋理ID,對應於OpenGL中一張Texture中的Gluint,注意此Texture爲一張旋轉的External OES Texture,必須搭配DisplayUvCoords信息才能正確渲染(OES Texture與普通紋理有所區別,下文會舉例一個實戰issue)
Frame.CameraBuffer.AcquireCameraImageBytes 可獲得Camera的原始相機數據,格式爲YUV420_888,此格式爲Android Camera2的默認格式(注意此格式將YUV分離爲3個Stride,與Camera1的NV21有所不同)。獲得原始數據一般用於進一步的圖像處理或CV算法
Frame.Pose.position Frame.Pose.rotation 包含了運動追蹤的結構體,包括相機當前位置、旋轉等

環境理解相關

Session.GetTrackable 可以獲得已經被AR算法重建的平面
Frame.Raycast 從三維世界一個點沿一個方向發射出一條無限長的射線,在射線的方向上,一旦與現實世界的特徵點、平面產生碰撞,則返回碰撞對象包含的位置、方向及其他相關屬性

光估計相關

Frame.LightEstimate.pixelIntensity 可以獲得當前估計的光照強度

ARCore兼容性及解決方案

目前ARCore支持的機型主要爲17年、18年發佈的旗艦機,下圖列了支持的國內主流設備列表,觀察到表中支持的設備主要爲高通芯片和ARM芯片,據官方所述後續還會支持聯發科芯片的機型。

OEM Model
小米 Mi Mix 2S, Mi Mix 3 Mi 8, Mi 8 SE
華爲 Honor 10, Honor Magic 2, Maimang 7 Mate 20, Mate 20 Pro, Mate 20 X nova 3, nava 3i P20, P20 Pro Porsche Design Mate RS Porsche Design Mate 20 RS
三星 Galaxy Note9 Galaxy S9, Galaxy S9+

值得一提的是Google官方考慮到國內用戶無法在Google Play安裝/更新ARCore Runtime,提供了小米、華爲和三星應用商店作爲國內安裝跳轉鏈接。

用於保證機型覆蓋率,我們選用了網易的InsightSDK 作爲ARCore的fallback的方案,開發的時候可以通過官網的ARCore設備白名單或者Session.CheckApkAvailability的方式進行自動選擇SDK。

開發者可能會遇到的問題

1. 運動中做運動跟蹤

例如,如果用戶是在火車上使用ARCore,這時IMU(Inertial Measurement Unit)獲取的數據不僅包括用戶的移動(實際是加速度),也包括火車的移動數據(實際是加速度),這樣將導致跟蹤失敗。

2. 跟蹤動態的環境

例如,如果用戶對着一面大白牆、波光粼粼的湖面,這時從攝像機獲取到的圖像信息是不穩定的,這將導致特徵點提取出錯進而導致跟蹤失敗。

3. 熱飄移

相機與 IMU 都是對溫度敏感的元器件,之前我們說過相機和IMU的OEM校準,但這個校準通常都會在某一個或者幾個特定溫度下進行,但在用戶設備使用過程中,隨着時長的延長會導致設備發熱,發熱就會影響到相機獲取的圖像的顏色信息和IMU測量的加速度信息準確性,表現出來就是跟蹤的物體會飄移。

4. CPU搶佔

從上面的ARCore算法中發現AR算法對CPU要求較高。如果你的App佔用了過多的CPU,依然會導致ARCore的效果不穩。可以使用類似SnapDragon Profiler的工具進行一個性能排查。

5. 使用Linear渲染模式

爲了追求正確的光照計算,我們使用了Linear渲染模式,但是ARCore並沒有提供Linear模式下相關的shader。可以使用以下函數對顏色空間進行轉換:

pow(gl_FragColor.rgb,vec3(2.2));

6. External OES Texture的特殊性

將Camera Texture渲染到屏幕的shader使用的是External OES Texture,在實際的使用過程中發現單獨使用External OES Texture沒有問題,但是結合一張正常Texture會渲染成黑色,經過排查問題發現External OES Texture的底層實現是多個單通道Texture的打包,所以在External OES Texture之後Bind的正常GLuint可能會錯誤的綁定,這個時候可以將External OES Texture放在最後即可解決。

7. 結合計算機視覺

因爲需要將Camera的相機數據做進一步數字圖像處理或者CV檢測,除了直接獲得TextureID,還需要獲得相機Buffer,但是小米手機調用Frame.acquireCameraImage() API會拋出NotYetAvailableException,官方文檔有在小米的手機上說明這個問題,所以使用這個API還不能做到完全統一兼容。

總的來說,儘管ARCore推出的時間較ARKit遲,但功能上基本與ARKit持平。並且回顧ARCore近一年的發展上看,ARCore也在率先提出一些行業標準,像Cloud Anchor這樣的新feature就是由ARCore率先提出,由此可見Google對ARCore的投入和在AR領域決心。同樣,社交化的應用方式也是AR技術落地的重要場景。預計未來幾年AR的開發生態會逐步完善並標準化,對開發者來說是十分值得期待的。

本文作者:鄧志鵬,網易人工智能事業部資深技術美術專家,《Unity5.x從入門到精通》作者之一,主要關注於將AI、AR等前沿技術用於圖形、交互領域。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章