廖書航
(四川大學(xué)視覺合成圖形圖像技術(shù)國防重點學(xué)科實驗室,成都 610065)
目前,市面上的增強現(xiàn)實(AR)應(yīng)用大致可以分為3類,即基于圖片或二維碼的AR應(yīng)用,基于人臉特征的AR應(yīng)用,和基于視覺SLAM的AR應(yīng)用?;趫D片或二維碼的AR應(yīng)用將虛擬信息渲染到圖片或二維碼上,一般會要求事先準(zhǔn)備一張圖片或者二維碼,并拍攝圖片或二維碼的俯視圖,然后利用對極幾何等知識求解出虛擬物體的渲染位置和角度[1]?;谌四樚卣鞯腁R應(yīng)用提取并跟蹤人臉特征,然后根據(jù)人臉特征的位置將虛擬的信息疊加到人臉上。基于視覺SLAM的AR應(yīng)用則利用視覺SLAM來實時計算真實環(huán)境中攝像機的運動,用該運動來控制渲染引擎中相機的位置和角度,并結(jié)合SLAM計算出的稀疏點云來放置虛擬物體。
但是,目前大部分基于視覺SLAM的AR應(yīng)用都只會利用視覺SLAM稀疏點云中一塊屬于平面的點云,并將虛擬物體放置在基于該平面點云擬合的虛擬平面上,一方面是因為對整個稀疏點云做網(wǎng)格重建會非常耗時,一方面是因為視覺SLAM估算出的稀疏點云包含非常多的噪點,對整個稀疏點云做網(wǎng)格重建難度很大。
本文設(shè)計了一個基于視覺SLAM稀疏點云的增強現(xiàn)實應(yīng)用,對視覺SLAM整個稀疏點云做了網(wǎng)格重建,在保證了一定的實時性下,提高了AR應(yīng)用與真實環(huán)境的交互程度和真實感。
SLAM是即時定位與建模(Simultaneous Localiza?tion and Mapping)的縮寫。根據(jù)所采用的傳感器,SLAM可以分為基于激光的SLAM,基于攝像頭的SLAM,即視覺SLAM(vSLAM),以及基于攝像頭和慣性測量單元(IMU)融合的視覺慣性導(dǎo)航系統(tǒng)(VINS)等。一個完整的視覺SLAM系統(tǒng)由四部分組成,分別為前端視覺里程計、后端優(yōu)化、回環(huán)檢測和建圖[2]。前端視覺里程計負責(zé)估算相鄰圖像間相機的運動以及局部地圖。后端優(yōu)化負責(zé)得到全局一致的攝像頭軌跡和地圖?;丨h(huán)檢測模塊判斷攝像頭是否曾經(jīng)到達過當(dāng)前的位置。建圖模塊則維護一個全局的點云地圖。
本文設(shè)計的增強現(xiàn)實應(yīng)用包含4大模塊,分別為渲染模塊、單目視覺SLAM模塊、網(wǎng)格生成模塊,以及重力方向求解模塊,運行流程見圖1。
渲染模塊使用Unity游戲引擎,用C#語言進行開發(fā),主要負責(zé)虛擬信息的渲染、使用C#重寫的OpenCV插件獲取攝像頭的圖片、人機交互以及游戲攝像機的控制等。
在本文設(shè)計的AR應(yīng)用中,游戲攝像機將模擬真實場景中攝像機的運動,這與許多基于視覺SLAM的AR應(yīng)用固定游戲攝像機的方式不同。當(dāng)啟動該AR應(yīng)用時,渲染模塊會將采集的圖片傳遞給單目視覺SLAM模塊,SLAM模塊會根據(jù)采集的圖片計算出真實場景中攝像機的運動,再將該運動傳回Unity游戲引擎。Unity游戲引擎會用這個運動來設(shè)置游戲攝像機的位置和旋轉(zhuǎn),從而讓游戲攝像機和真實場景中的攝像機的運動保持一致。而真實攝像機采集的圖片會放置于Unity中的一個面板上,該面板與游戲攝像機固連在一起,跟著游戲攝像機移動,充當(dāng)著Unity渲染的背景。
圖1 本文AR應(yīng)用的流程圖
隨著LSDSLAM以及ORBSLAM等開源庫出現(xiàn),單目視覺SLAM的研究也變得火熱起來。單目視覺SLAM可以分為直接法以及間接法,直接法以優(yōu)化光度誤差來求解攝像機的運動,可以在一定程度上應(yīng)對紋理缺失的場景。間接法計算特征點描述子并用描述子來做特征點跟蹤,并通過特征點匹配對求解攝像機運動,具有更高的魯棒性。
本文的單目視覺SLAM模塊使用ORBSLAM這一個間接法視覺SLAM開源庫,用C++語言開發(fā)。ORB?SLAM是一個多功能且較為魯棒的SLAM系統(tǒng),支持單目、雙目和RGBD視覺傳感器。由于ORBSLAM的原生環(huán)境是Linux,而本文設(shè)計的應(yīng)用是在Windows 7上開發(fā)的,所以需要做ORBSLAM的代碼移植,并與網(wǎng)格生成模塊以及重力方向求解模塊一同封裝成C++語言動態(tài)鏈接庫(DLL),供Unity游戲引擎調(diào)用。需要注意的是,ORBSLAM采用右手坐標(biāo)系,而Unity游戲引擎則使用左手坐標(biāo)系,那么需要一個坐標(biāo)變換矩陣將ORBSLAM計算出攝像機運動變換到Unity坐標(biāo)系下。
單目視覺SLAM計算出的關(guān)于周圍場景的點云非常稀疏,在紋理缺失的地方往往沒有點云對應(yīng),例如桌子的表面。如果直接使用點云庫(PCL)中的泊松重建或貪婪三角等算法對上述稀疏點云進行網(wǎng)格重建,則會發(fā)現(xiàn)在紋理缺失的地方會出很大的洞。另外,單目視覺SLAM計算出的點云還帶有許多噪點,這加大了網(wǎng)格生成的難度。
本文的網(wǎng)格生成模塊使用開源庫OpenMVS,用C++語言開發(fā)。OpenMVS是一個功能非常強大的三維重建開源庫,以稀疏點云、攝像機的初始姿態(tài)以及圖片為輸入,通過重新提取、匹配圖片中高質(zhì)量的特征點以及塊匹配,可以對稀疏點云進行去噪和補洞,最終生成稠密點云、網(wǎng)格以及紋理網(wǎng)格,被廣泛運用在測繪以及高精度建模。但OpenMVS的網(wǎng)格重建往往非常耗時,所以本文對OpenMVS的代碼和參數(shù)設(shè)置進行了一定的優(yōu)化,并將網(wǎng)格生成模塊放置于一個額外的線程,用于提高整個AR應(yīng)用的人機交互體驗。
需要注意的是,由于網(wǎng)格生成模塊以O(shè)RBSLAM生成的稀疏點云為輸入,并輸出三角網(wǎng)格,所以最終生成的網(wǎng)格定義于右手坐標(biāo)系,導(dǎo)致三角網(wǎng)格三個頂點的索引順序在Unity游戲引擎的攝像機下為逆時針方向。Unity游戲引擎為了提高渲染性能,只會渲染順時針頂點索引的三角網(wǎng)格,即三角網(wǎng)格只會顯示一面[3]。此處需要交換三角網(wǎng)格中第一個頂點和第三個頂點的索引。
重力方向求解模塊負責(zé)計算出真實環(huán)境中重力的方向,供Unity游戲引擎使用,采用C++語言開發(fā)。由于本文設(shè)計的AR應(yīng)用僅使用了一個攝像頭,所以無法直接測量出真實環(huán)境中的重力方向。當(dāng)攝像機對準(zhǔn)真實環(huán)境中的一塊水平平面時,點擊Unity中的重力方向求解按鈕,重力方向求解模塊便會對屬于該水平平面的稀疏點云做平面擬合,并求解出擬合平面的法向量。
具體做法為:
(1)累加點云平面中所有的三維點的坐標(biāo),求解坐標(biāo)平均值,該坐標(biāo)平均值為點云平面的幾何中心點O,點O應(yīng)位于擬合平面上。
(2)將點云平面中的三維點變換到以幾何中心點O為原點的坐標(biāo)系下,并由變換后的點云建立矩陣A。矩陣A的列為三維點的坐標(biāo)分量,行數(shù)為點云中點的個數(shù)。
(3)設(shè)擬合平面的法向量為X,利用奇異值分解(SVD)解超定方程組AX=0便可以求出法向量[4]。該法向量的反方向便是真實環(huán)境中的重力方向。最后,將該法向量的反方向設(shè)置為Unity游戲引擎中的重力方向。
本文AR應(yīng)用的開發(fā)環(huán)境為Windows 7系統(tǒng),CPU為Intel i7-3600QM 2.30GHz,在不使用GPU加速的情況下運行幀率可以達到10Hz以上,多線程下網(wǎng)格的生成大概會耗時3秒。在網(wǎng)格生成期間,AR應(yīng)用可以與用戶進行正常交互。AR應(yīng)用測試的場景包含兩個紙盒以及一張紋理豐富的背景圖,具體的效果可以參考圖2。從圖2可以出,虛擬的石頭可以與兩個木盒進行碰撞,并且虛擬石頭的陰影可以顯示在盒子上,這是因為AR應(yīng)用的虛擬網(wǎng)格是基于整個視覺SLAM的稀疏點云來生成的,而不是僅僅對屬于平面的點云進行了網(wǎng)格重建。本文AR應(yīng)用生成的網(wǎng)格可以參考圖3。
圖2 本文AR應(yīng)用的演示圖
圖3 本文AR應(yīng)用生成的網(wǎng)格
總的來說,本文提出的基于視覺SLAM稀疏點云的增強現(xiàn)實應(yīng)用在一定程度上提高AR應(yīng)用與真實場景的交互程度以及真實感,但魯棒性還不夠高。
當(dāng)攝像機劇烈運動或者大角度移動時,比如從桌子上方的俯視視角移動到與桌子平行的視角,虛擬物體可能會偏離真實環(huán)境的對應(yīng)位置。這是因為ORB?SLAM中前端里程計是基于特征點的。要想計算出兩幀圖片間準(zhǔn)確的攝像機運動,ORBSLAM需要較多的、正確的特征點匹配對。然而,當(dāng)攝像機劇烈運動時,連續(xù)圖片幀的視差很大,正確有效的特征點匹配對的數(shù)量往往不足,最終導(dǎo)致無法計算出攝像機運動或者計算出誤差很大的攝像機運動。
可以通過將單個攝像頭與慣性測量單元(IMU)融合來一定程度上解決上述問題。攝像頭與慣性測量單元是互補的。攝像頭可以提供豐富的信息,而慣性測量單元則可以在劇烈運動下提供較好的相機運動初值。另外,慣性測量單元中的加速度計可以測出真實尺度的平移以及重力方向,這樣就不用去擬合一個點云平面來求解重力方向了。