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

weixin_33763244發表於2019-01-24

《網易戲精》是網易人工智慧事業部旗下一款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後,之後作為核心服務自動更新。

ARKitARCore
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從三維世界一個點沿一個方向發射出一條無限長的射線,在射線的方向上,一旦與現實世界的特徵點、平面產生碰撞,則返回碰撞物件包含的位置、方向及其他相關屬性

光估計相關

ARCore相容性及解決方案

目前ARCore支援的機型主要為17年、18年釋出的旗艦機,下圖列了支援的國內主流裝置列表,觀察到表中支援的裝置主要為高通晶片和ARM晶片,據官方所述後續還會支援聯發科晶片的機型。

OEMModel
小米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等前沿技術用於圖形、互動領域。

相關文章