你可能已經(jīng)(或可能沒有)聽過(guò)或看過(guò)增強(qiáng)現(xiàn)實(shí)電子游戲隱形妖怪或Topps推出的3D棒球卡。其主要思想是在平板電腦,PC或智能手機(jī)的屏幕上,根據(jù)卡片的位置和方向,渲染特定圖形的3D模型到卡片上。
圖1:隱形妖怪增強(qiáng)現(xiàn)實(shí)卡。
上個(gè)學(xué)期,我參加了計(jì)算機(jī)視覺課程,對(duì)投影幾何學(xué)的若干方面進(jìn)行了研究,并認(rèn)為自己開發(fā)一個(gè)基于卡片的增強(qiáng)現(xiàn)實(shí)應(yīng)用程序?qū)⑹且粋€(gè)有趣的項(xiàng)目。我提醒你,我們需要一點(diǎn)代數(shù)來(lái)使它工作,但我會(huì)盡量少用。為了充分利用它,你應(yīng)該輕松使用不同的坐標(biāo)系統(tǒng)和變換矩陣。
<免責(zé)聲明
首先,這篇文章并不是一個(gè)教程,也不會(huì)涉及計(jì)算機(jī)視覺技術(shù)的全面指南或解釋,我只提及后續(xù)工作所需的要點(diǎn)。不過(guò),我鼓勵(lì)你深挖這一路上出現(xiàn)的概念。
其次,不要指望一些專業(yè)的結(jié)果。我這樣做只是為了好玩,而且我做的很多決策本可以做的更好。文章的主要思想是開發(fā)一個(gè)概念驗(yàn)證應(yīng)用程序。
/免責(zé)聲明>
說(shuō)到這里,后面的我負(fù)責(zé)了。
我們從哪里開始?
從整體上看這個(gè)項(xiàng)目可能會(huì)比實(shí)際上更困難。所幸的是,我們能夠把它劃分成更小的部分,當(dāng)這些部分合并在一起時(shí),我們就可以使增強(qiáng)現(xiàn)實(shí)應(yīng)用程序工作了。現(xiàn)在的問(wèn)題是,我們需要哪些更小的塊?
讓我們仔細(xì)看看我們想要達(dá)到的目標(biāo)。如前所述,我們希望在屏幕上投影一個(gè)圖形的三維模型,其位置和方向與某個(gè)預(yù)定義平面的位置和方向相匹配。此外,我們希望實(shí)時(shí)進(jìn)行,這樣,如果平面改變其位置或方向,投影模型就會(huì)相應(yīng)地改變。
為了實(shí)現(xiàn)這一點(diǎn),我們首先必須能夠識(shí)別圖像或視頻幀中的參考面。一旦確定,我們可以輕松確定從參考面圖像(2D)到目標(biāo)圖像(2D)的轉(zhuǎn)換。這種變換叫做單應(yīng)。但是,如果我們想要將放置在參考面頂部的3D模型投影到目標(biāo)圖像上,我們需要擴(kuò)展前面的變換來(lái)處理參考面坐標(biāo)系中要投影點(diǎn)的高度不是零的情況。這可以用一些代數(shù)來(lái)實(shí)現(xiàn)。最后,我們將這個(gè)轉(zhuǎn)換應(yīng)用到我們的3D模型并在屏幕上繪制。考慮到前面的觀點(diǎn),我們的項(xiàng)目可以分為:
1、識(shí)別參考平面。
2、估計(jì)單應(yīng)性。
3、從單應(yīng)性推導(dǎo)出從參考面坐標(biāo)系到目標(biāo)圖像坐標(biāo)系的轉(zhuǎn)換。
4、在圖像(像素空間)中投影我們的3D模型并繪制它。
圖2:概述增強(qiáng)現(xiàn)實(shí)應(yīng)用程序的整個(gè)過(guò)程。
我們將使用的主要工具是Python和OpenCV,因?yàn)樗鼈兌际情_源的,易于建立和使用,并且使用它們能快速構(gòu)建原型。用到代數(shù),我將使用numpy。
識(shí)別目標(biāo)表面
從對(duì)象識(shí)別的許多可能的技術(shù)中,我決定用基于特征的識(shí)別方法來(lái)解決這個(gè)問(wèn)題。這種方法不深入細(xì)節(jié),包括三個(gè)主要步驟:特征檢測(cè)或提取、特征描述和特征匹配。
特征提取
大體而言,這一步驟包括先在參考圖像和目標(biāo)對(duì)象中尋找突出的特征,并以某種方式描述要識(shí)別的對(duì)象的一部分。這些特征稍后可以用于在目標(biāo)對(duì)象中查找參考對(duì)象。當(dāng)目標(biāo)對(duì)象和參考圖像之間找到一定數(shù)量的正特征匹配時(shí),我們假設(shè)已經(jīng)找到目標(biāo)。為了使之工作,重要的是要有一個(gè)參考圖像,在那里唯一能看到的是要被發(fā)現(xiàn)的物體(或表面,在這種情況下)。我們不想檢測(cè)不屬于表面的特征。而且,雖然我們稍后會(huì)處理這個(gè)問(wèn)題,但是當(dāng)我們估計(jì)場(chǎng)景中表面的樣子時(shí),我們將用到參考圖像的尺寸。
對(duì)于要被標(biāo)記為特征的圖像的區(qū)域或點(diǎn),它應(yīng)該有兩個(gè)重要的屬性:首先,它應(yīng)該至少在本地呈現(xiàn)一些唯一性。這方面典型的例子可能是角或邊。其次,因?yàn)槲覀兪孪炔恢浪鞘裁矗纾谖覀兿胍R(shí)別它的圖像中,同一物體的方向、尺度或亮度條件,理想情況下,應(yīng)該是不變的變換,即不變的尺度、旋轉(zhuǎn)或亮度變化。根據(jù)經(jīng)驗(yàn),越恒定越好。
圖3:左側(cè),從我將使用的表面模型中提取的特征。右側(cè),從場(chǎng)景中提取的特征。注意,最右側(cè)圖形的角落是如何檢測(cè)為興趣點(diǎn)的。
特征描述
一旦找到特征,我們應(yīng)該找到它們提供的信息的適當(dāng)表示形式。這將允許我們?cè)谄渌鼒D像中尋找它們,并且還可以獲取比較時(shí)兩個(gè)檢測(cè)到的特征相似的度量。描述符提供由特征及其周圍環(huán)境給出的信息的表示。一旦描述符被計(jì)算出來(lái),待識(shí)別的對(duì)象就可以被抽象成一個(gè)特征vector,該vector包含圖像和參考對(duì)象中發(fā)現(xiàn)的關(guān)鍵點(diǎn)的描述符。
這當(dāng)然是個(gè)好注意,但實(shí)際上該怎么做呢?有很多算法可以提取圖像特征并計(jì)算其描述符,因?yàn)槲也粫?huì)更詳細(xì)地討論(整篇文章可能僅限于此),如果你有興趣了解更多的話,可以看看SIFT, SURF,或 Harris。我們將使用在OpenCV實(shí)驗(yàn)室開發(fā)的,它被稱為ORB(Oriented FAST and Rotated BRIEF)。描述符的形狀和值取決于所使用的算法,在我們的例子中,所獲得的描述符將是二進(jìn)制字符串。
使用OpenCV,通過(guò)ORB探測(cè)器提取特征及其描述符很容易:
特征匹配
一旦我們找到了對(duì)象和場(chǎng)景的特征,就要找到對(duì)象并計(jì)算它的描述符,是時(shí)候?qū)ふ宜鼈冎g的匹配了。最簡(jiǎn)單的方法是取第一個(gè)組中每個(gè)特征的描述符,計(jì)算第二組中所有描述符的距離,并返回最接近的一個(gè)作為最佳匹配 (在這里我要指出,選擇一種與使用的描述符相匹配的距離測(cè)量方法很重要。因?yàn)槲覀兊拿枋龇嵌M(jìn)制字符串,所以我們將使用明漢距離)。這是一種暴力方法,而且存在更先進(jìn)的方法。
例如,我們將使用的,我們可以檢查,前面解釋過(guò)的匹配從第二組向第一組方向來(lái)計(jì)算匹配時(shí)也是最好的匹配。這意味著這兩個(gè)特征相互匹配。一旦兩個(gè)方向的匹配完成,我們只接受滿足先前條件的有效匹配。圖4顯示了使用該方法找到15個(gè)最佳匹配項(xiàng)。
減少誤報(bào)數(shù)量的另一種選擇是檢查到第二個(gè)最佳匹配的距離是否低于某一閾值。如果是,那么匹配被認(rèn)為是有效的。
圖4:參考面和場(chǎng)景之間找到最接近的15個(gè)暴力匹配
最后,在找到匹配之后,我們應(yīng)該定義一些標(biāo)準(zhǔn)來(lái)決定對(duì)象是否被找到。為此,我定義了應(yīng)該找到的最小匹配數(shù)的閾值。如果匹配的數(shù)量高于閾值,則我們假設(shè)對(duì)象該已經(jīng)被找到。否則,我們認(rèn)為沒有足夠的證據(jù)表明識(shí)別是成功的。
使用OpenCV ,所有這些識(shí)別過(guò)程都可以用幾行代碼完成:
最后要說(shuō)明的是,在進(jìn)入這個(gè)過(guò)程的下一步之前,我必須指出,因?yàn)槲覀兿胍粋€(gè)實(shí)時(shí)的應(yīng)用程序,所以最好是實(shí)現(xiàn)一個(gè)跟蹤技術(shù),而不僅僅是簡(jiǎn)單的識(shí)別。這是因?yàn)椋瑢?duì)象識(shí)別將獨(dú)立地在每個(gè)幀中執(zhí)行,而不考慮以前的幀,這可以添加引用對(duì)象位置的有價(jià)值的信息。另一件需要考慮的事是,找到參考面越簡(jiǎn)單檢測(cè)越健壯。從這個(gè)特定的意義上,我使用的參考面可能不是最佳的選擇,但它有助于理解過(guò)程。
單應(yīng)估計(jì)
一旦我們識(shí)別當(dāng)前幀的參考面而且有一組有效匹配,我們可以估計(jì)兩幅圖之間的單應(yīng)。前面已經(jīng)解釋過(guò),我們想要找到將點(diǎn)從參考面映射到圖像平面的轉(zhuǎn)換(參見圖5)。這個(gè)轉(zhuǎn)換必須更新我們處理的每個(gè)新幀。
圖5:平面和圖像之間的單應(yīng)。來(lái)源: F. Moreno.
我們?cè)趺茨苷业竭@樣的轉(zhuǎn)變呢?既然我們已經(jīng)找到了兩幅圖像之間的一組匹配,我們當(dāng)然可以直接通過(guò)任何現(xiàn)有的方法(我提議使用RANSAC)找到一個(gè)同構(gòu)轉(zhuǎn)換來(lái)執(zhí)行映射,但讓我們了解一下我們正在做什么(見圖6)。如果需要,你可以跳過(guò)以下部分(在圖10之后繼續(xù)閱讀),因?yàn)槲抑粫?huì)解釋我們將要估計(jì)的轉(zhuǎn)換背后的原因。
我們所擁有的是一個(gè)具有已知坐標(biāo)的對(duì)象(在這種情況下是一個(gè)平面),比方說(shuō)世界坐標(biāo)系,我們用位于相對(duì)于世界坐標(biāo)系的特定位置和方向的攝像機(jī)拍攝它。我們假定相機(jī)遵循針孔模型工作,這大致意味著穿過(guò)3D點(diǎn)p和相應(yīng)的2D點(diǎn)u的光線相交于攝像機(jī)的中心c。如果你有興趣了解更多關(guān)于針孔模型的知識(shí),這里有一個(gè)好的資源。
圖6:成像假定為針孔成像模型。來(lái)源:F. Moreno.
雖然不是完全正確的,但針孔模型假設(shè)簡(jiǎn)化了我們的計(jì)算,并對(duì)于我們的目的來(lái)說(shuō)工作得很好。如果我們假設(shè)可以計(jì)算為針孔照相機(jī)(公式的推導(dǎo)作為練習(xí)留給讀者),則點(diǎn)p在相機(jī)坐標(biāo)系統(tǒng)中表示為u,v坐標(biāo)(圖像平面中的坐標(biāo)):
圖7: 成像假定為針孔成像模型。來(lái)源: F. Moreno。
在焦距是從針孔到圖像平面的距離的情況下,光學(xué)中心的投影是光學(xué)中心在圖像平面的位置,k是縮放因子。前面的方程告訴我們圖像是如何形成的。然而,如前所述,我們知道點(diǎn)p在世界坐標(biāo)系而不是相機(jī)坐標(biāo)系中的坐標(biāo),因此我們必須添加另一個(gè)將世界坐標(biāo)系中的點(diǎn)映射到相機(jī)坐標(biāo)系的轉(zhuǎn)換。根據(jù)變換,世界坐標(biāo)系中的p點(diǎn)的圖像平面坐標(biāo)是:
圖8:計(jì)算投影矩陣。來(lái)源: F. Moreno。
幸運(yùn)的是,由于參考面的點(diǎn)的z坐標(biāo)始終等于0(參考圖5),我們可以簡(jiǎn)化上面發(fā)現(xiàn)的轉(zhuǎn)換。很容易看出,z坐標(biāo)和投影矩陣的第三列的乘積將是0,所以我們可以將該列和z坐標(biāo)從前面的等式中刪除。將校準(zhǔn)矩陣重命名為A,并考慮到外部校準(zhǔn)矩陣是齊次變換:
圖9:簡(jiǎn)化投影矩陣。來(lái)源: F. Moreno。
從圖9我們可以得出結(jié)論,參考面與圖形平面之間的單應(yīng),這是我們從之前發(fā)現(xiàn)的匹配中估計(jì)出的矩陣:
圖10:參考平面和目標(biāo)圖像平面之間的單應(yīng)矩陣。來(lái)源: F. Moreno。
有幾種可以讓我們估計(jì)單應(yīng)矩陣的值,并且你可能熟悉其中的一些。我們將使用的是RANdom SAmple Consensus(RANSAC)。RANSAC是一種用于存在大量異常值的模型擬合的迭代算法,圖12列出了該過(guò)程的綱要。因?yàn)槲覀儾荒鼙WC我們發(fā)現(xiàn)的所有匹配都是有效的匹配,我們必須考慮有可能存在一些錯(cuò)誤的匹配(這將是我們的異常值),因此我們必須使用一種對(duì)異常值有效的估計(jì)方法。圖11說(shuō)明了如果我們認(rèn)為沒有異常值估計(jì)單應(yīng)時(shí),可能會(huì)存在的問(wèn)題。
圖11:存在異常值的單應(yīng)估計(jì)。來(lái)源: F. Moreno。
圖12:RANSAC算法概述。來(lái)源: F. Moreno。
為了說(shuō)明RANSAC如何工作,并且使事情更清楚,假設(shè)我們有一組要使用RANSAC擬合一條線的點(diǎn):
圖13:初始點(diǎn)集。來(lái)源: F. Moreno。
根據(jù)圖12所示的概述,我們可以推導(dǎo)出使用RANSAC擬合線的具體過(guò)程(圖14)。
圖14:RANSAC算法將一條線擬合到一組點(diǎn)。來(lái)源: F. Moreno。
運(yùn)行上述算法的一個(gè)可能的結(jié)果可以在圖15中看到。注意,該算法的前3個(gè)步驟只顯示第一次迭代(由右下角的數(shù)字表示),并且只顯示評(píng)分步驟。
圖15:使用RANSAC將一條線代入一組點(diǎn)。來(lái)源:F. Moreno。
現(xiàn)在回到我們的用例,單應(yīng)矩陣估計(jì)。對(duì)于單應(yīng)估計(jì),算法如圖16所示。由于它主要是數(shù)學(xué),所以我不會(huì)詳細(xì)討論為什么需要4個(gè)匹配或者如何估計(jì)H。但是, 如果你想知道為什么以及如何完成,這有一個(gè)很好的解釋。
圖16:用于單應(yīng)矩陣估計(jì)的RANSAC。來(lái)源: F. Moreno。
在看OpenCV如何為我們處理這個(gè)問(wèn)題之前,我們應(yīng)該討論一下算法的決定性的一個(gè)方面,就是匹配H的含義。它的主要含義是,如果在估計(jì)單應(yīng)性之后,我們將未用于估計(jì)的匹配映射到目標(biāo)圖像,那么參考面的投影點(diǎn)應(yīng)該接近目標(biāo)圖像中的匹配點(diǎn)。 如何認(rèn)為它們一致取決于你。
我知道要達(dá)到這一點(diǎn)很困難,但謝天謝地,在OpenCV中,使用RANSAC估計(jì)單應(yīng)很簡(jiǎn)單:
其中5.0是距離閾值,用來(lái)確定匹配與估計(jì)單應(yīng)是否一致。如果在估計(jì)單應(yīng)之后,我們將目標(biāo)圖像的參考面的四個(gè)角投影到一條線上,我們應(yīng)該期望得到的線將參考面包圍在目標(biāo)圖像中。我們可以這樣做:
結(jié)果是:
圖17:具有估算單應(yīng)的參考面的投射角。
我想今天就到這里了。在下一篇文章,我們將看到如何擴(kuò)展我們已經(jīng)估計(jì)的單應(yīng)矩陣,不僅可以在投影參考面上的點(diǎn),而且可以投影從參考面坐標(biāo)系到目標(biāo)圖像的任何3D點(diǎn)。我們將使用這個(gè)方法來(lái)實(shí)時(shí)計(jì)算,每個(gè)視頻幀的特定投影矩陣,然后從.obj文件選擇投影的視頻流3D模型。在下一篇文章的結(jié)尾,你可以看到類似于下面GIF中所看到的內(nèi)容:
與往常一樣,發(fā)布第2部分時(shí),我會(huì)上傳該項(xiàng)目的完整代碼和一些3D模型到GitHub供你測(cè)試。
-
增強(qiáng)現(xiàn)實(shí)
+關(guān)注
關(guān)注
1文章
712瀏覽量
44979 -
OpenCV
+關(guān)注
關(guān)注
31文章
635瀏覽量
41386 -
python
+關(guān)注
關(guān)注
56文章
4799瀏覽量
84817
原文標(biāo)題:Python+OpenCV實(shí)現(xiàn)增強(qiáng)現(xiàn)實(shí)(第1部分)
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論