詳解Oculus Rift的主動式光學(xué)定位技術(shù)
2016,VR元年,oculus、HTC、索尼等這樣的重量級廠商紛紛推出或宣布了自己的消費(fèi)級硬件產(chǎn)品來搶占消費(fèi)者市場,相信廣大VR愛好者們中的很多人都已經(jīng)入手了一款虛擬現(xiàn)實(shí)設(shè)備。在這些硬件當(dāng)中,Oculus Rift CV1(以下簡稱“CV1”)無疑是最受人矚目的硬件產(chǎn)品之一,畢竟它有2014年拿了Facebook20億美金這樣的大事件撐腰。
眾所周知,Oculus Rift采用的是主動式光學(xué)定位技術(shù),那它到底是如何實(shí)現(xiàn)的呢?
?。╲ia:nukethefridge.com)
基本實(shí)現(xiàn)流程:
Oculus Rift設(shè)備上會隱藏著一些紅外燈(即為標(biāo)記點(diǎn)),這些紅外燈可以向外發(fā)射紅外光,并用紅外攝像機(jī)實(shí)時拍攝。獲得紅外圖像后,將攝像機(jī)采集到的圖像傳輸?shù)接嬎銌卧?,通過視覺算法過濾掉無用的信息,從而獲得紅外燈的所在方向,再利用PnP算法,即利用四個不共面的紅外燈在設(shè)備上的位置信息、四個點(diǎn)獲得的圖像信息即可最終將設(shè)備納入攝像頭坐標(biāo)系,擬合出設(shè)備的三維模型,并以此來實(shí)時監(jiān)控玩家的頭部、手部運(yùn)動。
注:具體可看如下圖,注意上面這些紅色的小點(diǎn)點(diǎn)。
接下來我將向大家介紹一下我的推理過程,以及算法的一些細(xì)節(jié)。
| 頭顯上的LED燈
前文中我提到我們需要利用四個不共面的紅外燈在設(shè)備上的位置信息來進(jìn)行定位,而如果想要知道不同的紅外燈在設(shè)備上的位置信息,就必須能夠區(qū)分不同的紅外燈。
為什么這么說呢,如果不區(qū)分紅外燈,那么當(dāng)DK2(注:特指頭顯)在空間中運(yùn)動時,攝像機(jī)捕捉到光點(diǎn)后,要進(jìn)行關(guān)聯(lián)(姿態(tài)最優(yōu)匹配的過程)的次數(shù) 會非常大,舉個列子:
1) 如果有N預(yù)測圖像點(diǎn)和M 《= N觀察圖像點(diǎn),則有N!/(N-M)!可能的關(guān)聯(lián)
2) 對于N = 40和M = 20(對DK2 LED的數(shù)量),有3.3&TImes;1029的關(guān)聯(lián),所以就算是計算機(jī),也無法快速地得到結(jié)果。
很顯然,DK2一定是采用了某種先驗(yàn)的方式區(qū)分光點(diǎn)。那么問題來了,DK2到底是如何區(qū)分的呢?
我曾看到有文章中猜測說DK2是通過LED燈的亮滅來區(qū)分的,實(shí)際上卻并非如此。因?yàn)殡m然通過LED燈的亮滅來區(qū)分比較簡單,因?yàn)榱翜缱钊菀讌^(qū)分出來,但是這種方法有個缺陷,就是無法區(qū)分是姿態(tài)改變導(dǎo)致的LED燈被遮擋,還是LED燈本身就熄滅了,所以,DK2沒有使用這個方法,而是采用LED燈光信息的強(qiáng)弱來實(shí)現(xiàn)的。我們來觀察用灰度攝像機(jī)拍攝的圖:
對比上面兩圖,可以發(fā)現(xiàn)亮斑的大小有變化。可以看出紅色部分,在圖2時光斑更大,藍(lán)色則相反。接下里我們看詳細(xì)的做法。這里必須說一下,在推測具體的做法過程中,我曾誤以為DK2直接判斷光斑大小,然后根據(jù)多幀圖像的規(guī)律來判斷LED燈的ID,但實(shí)際上DK2是使用差分法來判斷光斑大小。我在這里簡單給大家介紹一下我的推理過程。
首先我用自己的攝像機(jī)拍攝了大量照片進(jìn)行觀察后發(fā)現(xiàn)如果把攝像機(jī)用60HZ左右頻率拍攝,圖像每10張就會開始重復(fù)。
我先給光點(diǎn)編個號,如下圖:
比如,2號點(diǎn)的可以用肉眼識別的強(qiáng)弱順序:弱,弱,強(qiáng),強(qiáng),弱,強(qiáng),弱,弱,弱,強(qiáng)。
那么是不是這樣呢?如何在DK2中表示這些強(qiáng)弱關(guān)系呢?
首先,已知SDK的windows的driver會發(fā)送一個開始信息,讓頭顯開始運(yùn)作;
緊接著,這個driver就會不斷接收到下面信息:
X1 X2 X3 X4 是1個32位數(shù),是圖像分析后得到的空間坐標(biāo)(原理后面給大家解釋),DX則不知道干什么用,但是觀察上面的num,換算出來是40,index從1開始,不斷遞增到40,說明DK2在一個一個的識別LED燈,另外,這些信息每17ms左右發(fā)上來一次,和60HZ的拍攝頻率差不多,基本上可以認(rèn)定是利用每10幀確定一個LED的方式。
為了完全確定這一點(diǎn),還必須確定另一個問題:同步。
如果真的是LED通過10幀不同的變化來讓攝像機(jī)確定LED燈的ID,那么必須要同步。
這要求一個同步信號能同時傳給攝像機(jī)和頭顯,如果能了解同步的時機(jī),就知道到底是不是60HZ的頻率了。
可是當(dāng)我看了MT9V034的資料后發(fā)現(xiàn)居然拍攝的頻率是30HZ左右,不過細(xì)想一下,如果使用差分檢測發(fā),使用30HZ這個頻率也能拍攝出光強(qiáng)的變化。也就是說,DK2根本不是直接判斷光斑是大還是小,而是將當(dāng)前幀的光斑與上一幀同一個光斑做對比,如果比之前大,則為大,反之則為小。那么當(dāng)一個新的幀到達(dá)時,該算法首先提取幀的亮像素斑點(diǎn),如下圖。忽略少于10個像素或不是圓盤狀的,最后確保所有的斑點(diǎn)來自前一幀中提取的大圓盤狀斑點(diǎn),然后進(jìn)行對比。
所以,DK2將當(dāng)前幀的光斑與上一幀同一個光斑做對比,然后根據(jù)10幀不同的變化來讓攝像機(jī)確定LED燈的ID。
我在進(jìn)一步查看這些點(diǎn)和位置信息的對應(yīng)關(guān)系后,總結(jié)出DK2判斷強(qiáng)弱變化的依據(jù)是:
1) 如果當(dāng)前幀的斑點(diǎn)比上一幀斑點(diǎn)大10%,就是0;
2) 如果當(dāng)前幀的斑點(diǎn)比上一幀斑點(diǎn)小10%,就是1;
3) 否則忽略。
這樣的設(shè)計非常好,防止了LED燈受到隨機(jī)干擾。