AVM(Around View Monitor),中文:全景環(huán)視系統(tǒng)。AVM已經(jīng)是一種較為成熟的技術(shù),中高端車型均有部署,但詳細(xì)講述AVM系統(tǒng)算法的技術(shù)博文并不多。作者在工作中搭建了一套AVM算法框架,有一些效果還不錯(cuò)的demo。本文主要是想將AVM算法框架中每個(gè)算子講述清楚,與大家共同進(jìn)步。本博文的風(fēng)格為理論與實(shí)踐結(jié)合,含有部分代碼,適合有一些計(jì)算機(jī)視覺基礎(chǔ)的同學(xué)。
作者仿真效果
01AVM系統(tǒng)概述
AVM汽車環(huán)視影像系統(tǒng)如圖所示,由安裝在前保險(xiǎn)杠、后備箱、后視鏡上的四個(gè)外置魚眼相機(jī)構(gòu)成。該系統(tǒng)包含的算子按照先后順序:去畸變、四路魚眼相機(jī)聯(lián)合標(biāo)定、投影變換、鳥瞰圖微調(diào)、拼接融合、3D模型紋理映射等。四路魚眼捕捉到的圖像信息通過上述算子,生成一個(gè)2D、3D的全景圖。AVM算法又分為離線階段和在線階段兩部分,在線階段是對(duì)離線階段的簡(jiǎn)化,更加適合于工程實(shí)現(xiàn)。下面我們來(lái)一一講述。
02離線階段算法pipeline
先來(lái)粗略瀏覽下AVM算法Pipeline包含哪些算子:
2DAVM
2D AVM Pipeline
3DAVM
2.1基于畸變表的魚眼相機(jī)去畸變
2.1.1 魚眼相機(jī)畸變模型
我們知道普通相機(jī)和廣角相機(jī)的投影方式一般為透視投影,即通過三角形相似原理,將相機(jī)坐標(biāo)系下三維世界中的物體投影到平面上,這是基于理想的透視投影模型(無(wú)畸變)。但實(shí)際情況是我們得到的最終圖像與理想的透視投影模型有一些區(qū)別,即徑向畸變(桶形、枕型)、切向畸變。因此相機(jī)標(biāo)定中都會(huì)對(duì)畸變做矯正。
魚眼相機(jī)的投影方式有很多種假設(shè),例如等距投影、等立體角投影、正交投影、體視投影、線性投影。但是真實(shí)的魚眼相機(jī)鏡頭并不完全遵循上述的這些模型假設(shè)。因此Kannala-Brandt提出了一種一般形式的估計(jì),適用于不同類型的魚眼相機(jī):
這個(gè)也是納入opencv中的魚眼相機(jī)畸變模型。對(duì)照下圖:
為光線入射角為出射光線在相機(jī)歸一化平面上或者在相機(jī)成像平面上與O之間的距離(在opencv中表示光線在相機(jī)歸一化平面上的成像位置)。
魚眼相機(jī)模型
相機(jī)去畸變通常使用張正友老師的棋盤格標(biāo)定方法,首先通過矩陣推導(dǎo)得到一個(gè)比較好的初始解,然后通過非線性優(yōu)化得到最優(yōu)解,包括相機(jī)的內(nèi)參、外參、畸變系數(shù),然后對(duì)魚眼圖像做去畸變處理。內(nèi)參即:
相機(jī)內(nèi)參矩陣
然而,張正友標(biāo)定法并不適用于我們的場(chǎng)景。
2.1.2 基于廠家畸變表的魚眼圖像去畸變
由于張正友老師的棋盤格標(biāo)定法是在圖像的全局進(jìn)行擬合得到一個(gè)全局的最優(yōu)解,因此需要保證多次拍攝到的標(biāo)定板的棋盤格可以覆蓋整個(gè)圖像區(qū)域。
而我們假設(shè)的場(chǎng)景為要求汽車整車上流水線進(jìn)行標(biāo)定,即相機(jī)已經(jīng)安裝在車上。很顯然,由于車身遮擋的原因,很難保證上述條件。另外,棋盤格標(biāo)定法并不適用于批量生產(chǎn)。因此,我們選擇了基于廠家提供的畸變表對(duì)魚眼相機(jī)圖像進(jìn)行去畸變。相機(jī)廠家都有專業(yè)的光學(xué)工程師,大廠提供的畸變表通常情況下比較準(zhǔn)確。當(dāng)然,也有一些在畸變表的基礎(chǔ)上進(jìn)行優(yōu)化的方法,例如[2]中采用最小重投影的方法計(jì)算出最優(yōu)的相機(jī)主點(diǎn)位置,然后使用畸變表進(jìn)行去畸變處理。在其他場(chǎng)景中,還有些同學(xué)先標(biāo)定出相機(jī)的內(nèi)參,然后將內(nèi)參與畸變表聯(lián)合使用。下面我們來(lái)講述基于畸變表的去畸變方法:
廠家提供的畸變表
上面的表格展示了相機(jī)畸變表的一部分,廠家給出了入射角從0°到90°的光線在焦距為f的相機(jī)真實(shí)成像平面上成像點(diǎn)距離成像平面中心的真實(shí)距離,單位為mm。如果想用opencv提供的API做去畸變處理,需要使用廠家提供的焦距,將換算到相機(jī)的歸一化平面上去(即除以)。然后通過多項(xiàng)式擬合的方法,計(jì)算出,,,,這幾個(gè)畸變參數(shù),例如可以使用python的curve_fit庫(kù)進(jìn)行多項(xiàng)式擬合。調(diào)用Opencv API,m_distortion_coeffs即為多項(xiàng)式擬合的畸變參數(shù)。
fisheye::initUndistortRectifyMap(m_intrinsic_matrix, m_distortion_coeffs, R, NewCoeff, image_size*2, CV_32FC1, mapx, mapy); cv::remap(disImg, undisImg, mapx, mapy, INTER_LINEAR);
通俗講:魚眼相機(jī)去畸變的過程實(shí)際上就是遍歷我們想要的無(wú)畸變圖上的坐標(biāo)點(diǎn),通過mapx,mapy兩個(gè)查找表,找到該坐標(biāo)點(diǎn)在畸變圖上的像素位置。通常這個(gè)像素的位置為浮點(diǎn)型,需要做雙線性插值。否則在紋理邊緣上會(huì)有鋸齒狀的問題,這個(gè)結(jié)論是作者實(shí)現(xiàn)了opencv remap函數(shù)驗(yàn)證過的,有興趣的同學(xué)可以自己實(shí)現(xiàn)一下mapping的過程(查找+插值)。來(lái)看圖:
魚眼圖 去畸變
右圖為基于畸變表去畸變的結(jié)果,可以看出去畸變的效果大體上滿足要求,例如柱子邊、標(biāo)定布邊、車道線為直線。但是仍有部分區(qū)域的去畸變效果不好,直線不夠直。這個(gè)問題會(huì)在鳥瞰圖中看起來(lái)更加突出,也是導(dǎo)致覆蓋區(qū)域拼接不齊的重要原因。原因可能有幾種:(1)相機(jī)光軸與成像平面的交點(diǎn)(主點(diǎn))與圖像平面的中心不重合,即內(nèi)參矩陣中的,。(2)廠家給的焦距不準(zhǔn)(3)廠家給的畸變表有誤差。
理論上講,相機(jī)的標(biāo)定是一個(gè)計(jì)算全局最優(yōu)解的過程,可以理解為:我的內(nèi)參可以不那么準(zhǔn),我拿到的畸變表也可以不那么準(zhǔn),但是只要我的優(yōu)化目標(biāo)重投影誤差很小,或者畸變?nèi)サ谋容^干凈,那么這個(gè)全局最優(yōu)解就是可以接受的。因此引用【2】中使用了最小化重投影誤差的方法得到內(nèi)參中,然后再使用畸變表;在有的場(chǎng)景中,還有些同學(xué)用棋盤格標(biāo)定出相機(jī)的內(nèi)參,然后配合畸變表進(jìn)行使用。這些內(nèi)容作者后面都會(huì)陸續(xù)做優(yōu)化。
2.2四路魚眼聯(lián)合標(biāo)定
魚眼相機(jī)聯(lián)合標(biāo)定的目的是要得到四個(gè)魚眼相機(jī)之間的位姿關(guān)系,然后將拍攝到的圖像搞到同一個(gè)坐標(biāo)系下得到一幅全景環(huán)視圖。
相機(jī)聯(lián)合標(biāo)定示意圖
如圖所示,全景鳥瞰圖的視野范圍是人為給定的參數(shù),可根據(jù)用戶喜好進(jìn)行調(diào)節(jié)。標(biāo)定布上的棋盤格大小、黑格子尺寸、汽車與標(biāo)定布之間的間距這些都是已知的先驗(yàn)信息。上述先驗(yàn)信息在現(xiàn)實(shí)世界中與在全景圖上的尺度關(guān)系為1:1,即1個(gè)像素代表1cm(當(dāng)然這個(gè)尺度也可以調(diào)節(jié),你想讓一個(gè)像素代表厘米也沒問題)。這樣做聯(lián)合標(biāo)定的意義在于:我們可以知道前、后、左、右四個(gè)魚眼相機(jī)去畸變后圖像中棋盤格上角點(diǎn),與前、后、左、右四個(gè)鳥瞰圖中棋盤格角點(diǎn)之間對(duì)應(yīng)的坐標(biāo)關(guān)系。這樣我們就可以根據(jù)投影變換,將整張圖像投影到對(duì)應(yīng)的鳥瞰圖上去。又由于在聯(lián)合標(biāo)定中,四個(gè)鳥瞰圖是剛好拼接到一塊的,因此利用上述方法將四張圖全部投影到鳥瞰圖上,在不考慮誤差的理想情況下,應(yīng)該是剛好拼接在一起的。以上,就是聯(lián)合標(biāo)定的思路。
2.3投影變換
2.3.1 投影變換原理
投影變換的通俗理解就是:假設(shè)同一個(gè)相機(jī)分別在A、B兩個(gè)不同位置,以不同的位姿拍攝同一個(gè)平面(重點(diǎn)是拍攝平面,例如桌面、墻面、地平面),生成了兩張圖象,這兩張圖象之間的關(guān)系就叫做投影變換。張正友老師的相機(jī)標(biāo)定法使用的就是從標(biāo)定板平面到圖像平面之間的投影模型。
投影變換模型
圖中相機(jī)從兩個(gè)不同的角度拍攝同一個(gè)平面,兩個(gè)相機(jī)拍攝到的圖像之間的投影變換矩陣(單應(yīng)矩陣)為:
其中為相機(jī)內(nèi)參矩陣,為兩個(gè)相機(jī)之間的外參。這個(gè)公式怎么推導(dǎo)的網(wǎng)上有很多,我們只需要知道,這個(gè)單應(yīng)矩陣內(nèi)部實(shí)際是包含了兩個(gè)相機(jī)之間的位姿關(guān)系即可。這也就解釋了:為什么有的AVM pipeline的方法是需要標(biāo)定相機(jī)的外參,然后通過廠家提供的相機(jī)安裝參數(shù)將四路魚眼全部統(tǒng)一到車身坐標(biāo)系下,而我們不需要這個(gè)過程,只需要用標(biāo)定布來(lái)做聯(lián)合標(biāo)定。其實(shí)兩種方法內(nèi)部都是相通的,都繞不開計(jì)算相機(jī)外參這件事情。
2.3.2 投影變換生成鳥瞰圖
生成鳥瞰圖的過程可以理解為:將魚眼相機(jī)拍攝到的圖像,投影到某個(gè)在汽車上方平行地面拍攝的相機(jī)的平面上去。這個(gè)單應(yīng)矩陣具體是多少,由去畸變圖中檢測(cè)到的棋盤格角點(diǎn)坐標(biāo)和聯(lián)合標(biāo)定全景圖中棋盤格角點(diǎn)坐標(biāo)來(lái)決定。如圖所示,以后置相機(jī)為例,聯(lián)合標(biāo)定已知圖(2)中框出棋盤格的坐標(biāo),圖(1)中的棋盤格坐標(biāo)可通過opencv的函數(shù)進(jìn)行檢測(cè),從而建立單應(yīng)矩陣H的求解模型。
(1)去畸變圖中棋盤格位置 (2)聯(lián)合標(biāo)定全景圖中棋盤格位置 (3)瞰圖
2.3.3 一些經(jīng)驗(yàn)之談
a. 盡量選擇更多的角點(diǎn)計(jì)算單應(yīng)矩陣
單應(yīng)矩陣的求解是一個(gè)擬合的過程,如果選用過少的點(diǎn),容易陷入局部最優(yōu)解。造成的結(jié)果是就是鳥瞰圖上只有你選擇的那些點(diǎn)可以正確的投影,其他像素的投影可能不正確。這一點(diǎn)有點(diǎn)類似于深度學(xué)習(xí)中訓(xùn)練樣本太少,導(dǎo)致過擬合的問題。
單應(yīng)矩陣三種形式(1)(2)(3)
上面公式可以看出,一對(duì)匹配點(diǎn)可以提供兩組方程,理論上4對(duì)匹配點(diǎn)就可以求解出單應(yīng)矩陣。Opencv求解單應(yīng)矩陣提供了兩個(gè)函數(shù),findHomography和getPerspectiveTransform。
getPerspectiveTransform的輸入是4對(duì)點(diǎn),對(duì)(2)中矩陣求逆。理想情況下這種方法是可行的,但由于存在噪聲,我們?cè)趫D像上檢測(cè)到的角點(diǎn)的誤差、標(biāo)定布棋盤格的誤差,這種方法極其不準(zhǔn)確。
findHomography求單應(yīng)矩陣的方法輸入點(diǎn)對(duì)很多,解一個(gè)超定方程(3)。經(jīng)過一頓推導(dǎo),單應(yīng)矩陣為(3)中矩陣的奇異值分解中最小奇異值對(duì)應(yīng)的特征向量。這種方法用于做擬合的樣本更多,最終的效果更好。而且Opencv還有很多優(yōu)化算法,例如基于ransac思想的單應(yīng)矩陣求解方法。當(dāng)然,為了提高效果,可以對(duì)標(biāo)定布進(jìn)行DIY,某寶上很多這種DIY標(biāo)定布,你想搞多少格子就搞多少。
如1.2所述,由于畸變?nèi)コ牟粡氐?,?dǎo)致有些直線仍然是彎曲的。這一現(xiàn)象在投影到鳥瞰圖上之后尤為明顯,通過大量的棋盤格點(diǎn)進(jìn)行投影變換,可以從一定程度上強(qiáng)制矯正這個(gè)問題。至少可以讓車身附近的全景圖效果更佳,而我們的avm系統(tǒng)最在意的恰好就是車身周圍這部分,距離車身遠(yuǎn)的部分也不會(huì)呈現(xiàn)出來(lái)。如圖所示為某廠DIY的標(biāo)定布示意圖。
DIY標(biāo)定布
b. 盡量讓棋盤格處于相機(jī)拍攝圖像的中心
魚眼相機(jī)在中心部分畸變小,邊緣位置畸變大。去畸變的結(jié)果通常也是中間的效果好,邊緣殘留的畸變多。因此,為了使單應(yīng)矩陣計(jì)算的更佳準(zhǔn)確,我們要保證標(biāo)定布擺放的時(shí)候棋盤格位于魚眼相機(jī)中央。這也是為什么某寶上標(biāo)定布使用的示意圖通常是圖(2)這種,而不是圖(1)。很顯然,圖(2)中棋盤格位于左側(cè)后視鏡附近(左魚眼相機(jī)就在左后視鏡上),即相機(jī)圖像的中間位置,而圖1中棋盤格則在相機(jī)圖像邊緣上。
左側(cè)魚眼相機(jī)鳥瞰圖(1)(2)
2.4拼接融合
經(jīng)過3中的投影變換,我們得到4張包含重疊區(qū)域的鳥瞰圖如圖所示,需要將這些鳥瞰圖進(jìn)行拼接融合。
鳥瞰圖
以左、前魚眼相機(jī)俯視圖為例,觀察下它們的重疊區(qū)域重疊區(qū)域:
白色為重疊區(qū)域、AB為前鳥瞰圖邊界、CD為右鳥瞰圖邊界
通常的做法是分別以AB、CD為邊界,計(jì)算白色區(qū)域像素點(diǎn)與AB、CD之間的距離,然后計(jì)算一個(gè)權(quán)重,距離CD越近的位置,前俯視圖權(quán)重越大;距離AB越近的位置,左俯視圖權(quán)重越大。但會(huì)出現(xiàn)邊界效應(yīng)如圖所示:
前俯視圖權(quán)重圖
其原因也很容易理解:如圖所示,將AB、CD延長(zhǎng)至O點(diǎn),在EAOCE這個(gè)區(qū)域內(nèi),使用上述方法計(jì)算權(quán)重圖才是一個(gè)完整連續(xù)的模型,如果在EABFDCE這個(gè)區(qū)域內(nèi)計(jì)算權(quán)重圖相當(dāng)于把一個(gè)完整連續(xù)的域強(qiáng)行截?cái)?,?jì)算得到的權(quán)重圖必然是有截?cái)嗪圹E的
完整、連續(xù)模型示意圖
因此需要使用某種策略,讓我們?cè)谝粋€(gè)連續(xù)的作用域上計(jì)算權(quán)重,這里提供一個(gè)思路[3]:在EAFCE這個(gè)連續(xù)的作用域中計(jì)算權(quán)重,
連續(xù)模型和權(quán)重圖
2.5基于光流的鳥瞰圖微調(diào)
在整個(gè)AVM系統(tǒng)中,廠家提供的畸變表、焦距、相機(jī)主點(diǎn)位置,聯(lián)合標(biāo)定使用的標(biāo)定布都會(huì)引入誤差。這些誤差會(huì)導(dǎo)致生成的鳥瞰圖在重疊區(qū)域有一些偏移。第4小節(jié)中的拼接融合模塊是為了讓鳥瞰圖在覆蓋區(qū)域過渡平滑,盡量避免偽影現(xiàn)象。但是我們不能將這個(gè)壓力全部施加給拼接融合模塊。因此需要在拼接融合模塊之前,對(duì)鳥瞰圖進(jìn)行微調(diào),這個(gè)微調(diào)功能是供客戶或者4S店人員進(jìn)行手動(dòng)調(diào)節(jié)的。
在調(diào)研中發(fā)現(xiàn),現(xiàn)在很多部署在車上的AVM系統(tǒng)都包含有微調(diào)功能。但大部分都存在一個(gè)問題:只能保證一邊是對(duì)齊的,另外一邊拼不齊。例如,前面對(duì)齊后面對(duì)不齊。
作者使用了[4],將前、后微調(diào)光流圖進(jìn)行融合,得到一個(gè)平緩過渡的光流圖,兼顧了前后兩側(cè)的微調(diào)。以左俯視圖為例,算法流程如下:
固定住前、后兩個(gè)鳥瞰圖
手動(dòng)微調(diào)左鳥瞰圖,使左鳥瞰圖與前鳥瞰圖之間的重疊區(qū)域貼合。記錄微調(diào)矩陣M1,并根據(jù)矩陣計(jì)算光流map1
手動(dòng)微調(diào)左鳥瞰圖,使左鳥瞰圖與后鳥瞰圖之間的重疊區(qū)域貼合。記錄微調(diào)矩陣M2,并根據(jù)矩陣計(jì)算光流map2
根據(jù)像素距離計(jì)算map1與map2的權(quán)重圖w,即距離前鳥瞰圖越近,map1的權(quán)重越大,反之則越小
使用w對(duì)map1和map2進(jìn)行加權(quán)融合
當(dāng)微調(diào)矩陣M1和M2方向正好相反時(shí),這個(gè)基于光流的思想可以很好地將兩者融合,因?yàn)榫仃囎儞Q是比較“硬”的一種數(shù)學(xué)方法,而光流卻像水一樣的“軟”。
左側(cè)為普通的融合效果 右側(cè)為基于光流思想微調(diào)后的效果
可以看出這個(gè)方法可以兼顧前、后的微調(diào)效果??梢岳斫鉃閷⑵唇訁^(qū)域的誤差均攤給中間的區(qū)域,而中間這部分區(qū)域不存在拼接融合的問題,而且我們?cè)诓窜嚨倪^程中更注重的是車與周圍物體的相對(duì)位置而非周圍物體的精確位置,因此實(shí)際看上去也沒什么問題。
最終的2D AVM 效果展示:
2D AVM Demo
2.6三維模型紋理映射
2D的AVM算法是基于投影變換,將魚眼圖像投影到鳥瞰圖上。而單應(yīng)變換有一個(gè)前提:就是平面假設(shè)。是把一個(gè)平面投影到另外一個(gè)平面。存在的問題是:圖像中所有的三維物體,例如汽車、柱子、墻,全部被當(dāng)成平面來(lái)處理。這些內(nèi)容在鳥瞰圖上會(huì)被拉的很長(zhǎng)
安裝在車身周圍的魚眼相機(jī)是單目相機(jī),單目相機(jī)不能獲取三維物體的深度。在圖形學(xué)中有一種真實(shí)感增強(qiáng)的方法:制作一個(gè)三維模型,把二維的紋理貼圖以某種方式映射到三維模型上,3D AVM正是使用了這個(gè)紋理映射技術(shù),為駕駛員呈現(xiàn)出一個(gè)偽3D的效果。
2.6.1 AVM 3D模型構(gòu)建
3D模型是由一個(gè)個(gè)小面片構(gòu)成的,可以是三角面片、多邊形面片等等。面片又是由多個(gè)頂點(diǎn)構(gòu)成的,例如三角面片對(duì)應(yīng)的就是3個(gè)頂點(diǎn)。
3dsMax三維模型
放大看可以看到,3D模型是由很多個(gè)小的多邊形面片構(gòu)成。3D模型的文件形式有很多種,但大體上都是包含:模型頂點(diǎn)、面片、紋理坐標(biāo)、法向量這些三維信息。具體如何使用3dsMax來(lái)制作3D模型,就不敘述了,作者不是專業(yè)的美工,方法可能不太聰明,領(lǐng)會(huì)精即可。
AVM 3D模型是一個(gè)碗狀的三維模型。模擬駕駛員視角,即汽車周圍附近是路面,這部分直接映射到碗底平面上;而距離汽車較遠(yuǎn)的位置可能是樓房、樹木、墻等三維物體,這部分內(nèi)容將使用某種方式映射到三維點(diǎn)上。下面展示的就是我們的3d模型中的必要信息,包含頂點(diǎn)坐標(biāo)、紋理坐標(biāo)、法向量、三角面片索引。
//頂點(diǎn)坐標(biāo) v 166.2457 190.1529 575.8246 v 169.0261 192.6147 575.0482 v 163.5212 194.2559 576.8094 v 160.4214 177.1097 576.3941 v 160.5880 183.6252 577.0156 ...... //紋理坐標(biāo) vt 0.227618 0.463987 vt 0.254011 0.468448 vt 0.251903 0.470549 vt 0.248436 0.466586 vt 0.267204 0.509296 ...... //法向量信息 vn 0.3556 -0.4772 -0.8036 vn 0.3606 -0.4537 -0.8149 vn 0.3145 -0.3999 -0.8609 vn 0.3101 -0.3998 -0.8626 vn 0.3170 -0.3811 -0.8685 ...... //三角面片信息 f 5825/5825/4368 5826/5826/4369 5827/5827/4370 f 5828/5828/4371 5829/5829/4372 5830/5830/4373 f 5831/5831/4374 5832/5832/4375 5833/5833/4376 f 5834/5834/4377 5835/5835/4378 5836/5836/4379 f 5837/5837/4380 5838/5838/4381 5839/5839/4382
2.6.2 三維模型紋理映射
這一小節(jié)講述的是:
(1)紋理映射是從哪里映射到哪里
(2)采用哪種策略進(jìn)行映射
我們的最終目標(biāo)是:找到3d模型上每個(gè)頂點(diǎn)對(duì)應(yīng)在魚眼2d圖像上的紋理坐標(biāo)。
作者采用的是一種基于虛擬相機(jī)思想的3d紋理映射方法[5],如圖所示:
基于虛擬相機(jī)思想的3d紋理映射模型
假設(shè)2D AVM的全景鳥瞰圖是由汽車正上方某個(gè)虛擬相機(jī)拍攝到的圖,將其當(dāng)作2D紋理,以透視投影的方法映射到3d模型上面。圖中Lw-Rw為全景俯視圖,虛擬相機(jī)與頂點(diǎn)A的直線在鳥瞰圖上的交點(diǎn)為A',從而得到A頂點(diǎn)對(duì)應(yīng)的2D紋理映射坐標(biāo)A'。然后通過逆投影變換H_inverse、畸變mapx、mapy查找到3d模型的頂點(diǎn)A在魚眼相機(jī)上的紋理坐標(biāo)。遍歷3d模型上的每一個(gè)點(diǎn),即可得到三維模型與魚眼相機(jī)紋理坐標(biāo)之間的映射關(guān)系:
根據(jù)透視投影原理,計(jì)算頂點(diǎn)A對(duì)應(yīng)的鳥瞰圖紋理A'
使用矩陣變換和單應(yīng)變換逆推A'在去畸變圖上的坐標(biāo)A1
通過去畸變的查找表map查找A1在魚眼相機(jī)畸變圖上的坐標(biāo)
遍歷上述過程,即可得到3D模型上所有頂點(diǎn)對(duì)應(yīng)魚眼圖上的紋理坐標(biāo)
具體流程如圖所示:
3d模型紋理映射流程
看下效果:這個(gè)模型的法向量是反的,所以渲染的結(jié)果光線有問題,非常的暗。不過可以看到偽3D的真實(shí)感增強(qiáng)效果,領(lǐng)會(huì)精神即可。
右側(cè)模型映射
2.6.3 三維融合
實(shí)際上作者使用的是前、后、左、右4個(gè)曲面模型,這4個(gè)曲面模型與4路魚眼圖像一一對(duì)應(yīng),這樣做是為了增加OpenGl渲染的并行,避免在做拼接融合時(shí)用到if、else這些判斷語(yǔ)句。上圖中的3d模型就是左側(cè)魚眼相機(jī)對(duì)應(yīng)的曲面模型。
我們先來(lái)回顧2D AVM的做法:生成鳥瞰圖,然后做融合。我們當(dāng)時(shí)生成的鳥瞰圖大小為10801080,這個(gè)分辨率等同于現(xiàn)實(shí)世界中的1080cm1080cm,足以顯示車身周圍。但是,這個(gè)范圍最多只能映射到3d碗模型的底部附近區(qū)域,如下圖:忽略邊上的鋸齒,那是渲染時(shí)插值的bug,先不去管他。從這圖可以看出:如果鳥瞰圖選的很小,會(huì)導(dǎo)致只映射到碗的底部。
小鳥瞰圖映射到模型上
我們把鳥瞰圖的尺寸放大,可以看到:
大鳥瞰圖映射到模型上
圖1為左側(cè)魚眼相機(jī)去畸變后的圖像,圖2是由圖1做投影變換得到的鳥瞰圖,圖3為映射到左側(cè)模型后的結(jié)果
這里要注意:在算法實(shí)現(xiàn)上不可以像2D AVM那樣,去真正地生成一個(gè)鳥瞰圖。從鳥瞰圖我們不難看出,在遠(yuǎn)離棋盤格的部分被嚴(yán)重拉長(zhǎng),而圖1中接近消失點(diǎn)、消失線的那些像素在鳥瞰圖上將會(huì)被拉到無(wú)窮遠(yuǎn)。可以這樣理解,圖一中的消失點(diǎn)、消失線表示:在當(dāng)前的相機(jī)位姿,某一個(gè)平面上(例如地面)的點(diǎn)全部在這條消失線以下。而鳥瞰圖相當(dāng)于我們把相機(jī)平行于地面進(jìn)行拍攝,那么地平面無(wú)窮遠(yuǎn)處(即1中的消失點(diǎn)、消失線)成像在鳥瞰圖中必然會(huì)被拉長(zhǎng)到無(wú)窮遠(yuǎn)處,就像圖2一樣。有興趣的同學(xué)可以看看消失點(diǎn)的解釋。
消失點(diǎn)
如果想要將整個(gè)碗狀模型填滿紋理,需要生成一個(gè)特別大的鳥瞰圖。即需要計(jì)算一個(gè)特別大的map,這個(gè)計(jì)算量是巨大的。因此在算法實(shí)現(xiàn)上,要選用遍歷模型上的每個(gè)頂點(diǎn),進(jìn)行逆向紋理映射的方法計(jì)算紋理坐標(biāo)(不再依賴于生成一個(gè)鳥瞰圖),頂點(diǎn)之間的空缺將由渲染引擎通過插值的方法進(jìn)行填充,這個(gè)是種成熟的技術(shù)。
講了這么多終于說到三維的融合。2D的融合是對(duì)鳥瞰圖的覆蓋區(qū)域做形態(tài)學(xué)操作,得到下圖,然后計(jì)算權(quán)重。而3D的算法強(qiáng)調(diào)的是離散點(diǎn)的思維,不會(huì)再生成一個(gè)超級(jí)大的鳥瞰圖。換句話說,算法不會(huì)再計(jì)算一個(gè)像下圖一樣覆蓋區(qū)域的圖像。因此,要尋找其他的方式來(lái)解決3D融合的問題。
左上角重疊區(qū)域
如圖所示[6]:
右上方重疊區(qū)域示意圖
大概思路就是計(jì)算3D頂點(diǎn)對(duì)應(yīng)鳥瞰圖的紋理坐標(biāo)B。通過AB與m、l的夾角與θ0計(jì)算權(quán)重。
當(dāng)然,重疊區(qū)域不可能這么理想,這個(gè)論文中的示意圖l和m正好交于A點(diǎn)。實(shí)際情況是它上面那個(gè)圖的樣子。需要使用某種專門針對(duì)3D AVM融合的策略來(lái)實(shí)現(xiàn)之[7]。將3D模型頂點(diǎn)對(duì)應(yīng)的權(quán)重圖映射到二維的示意圖:
放大看
總體來(lái)講,3D AVM算法就是先搞一個(gè)3維模型,然后通過紋理映射,將3維模型上的每一個(gè)頂點(diǎn)與二維的紋理圖進(jìn)行綁定。OpenGl利用上述數(shù)據(jù)進(jìn)行渲染。最終的3D效果后續(xù)會(huì)發(fā)上來(lái)。
03在線階段工程實(shí)現(xiàn)pipeline
前面介紹的是離線階段的算法流程,離線階段只有在流水線上或者4s店才會(huì)用到,是一個(gè)初始化的過程。初始化的內(nèi)容包括:畸變表、投影變換矩陣、紋理映射關(guān)系、拼接融合權(quán)重圖等。最重要的是要將去畸變、投影變換、紋理映射這些過程寫入一個(gè)查找表,存入內(nèi)存,在線處理的時(shí)候直接調(diào)用即可。附上部分代碼,對(duì)map做remap這塊可能會(huì)稍微難理解一些。
//4個(gè)label是鳥瞰圖在avm全景上的位置坐標(biāo) for (int i = label1; i < label2; i++) { float *map2_x = map2_xR.ptr9.1 2D AVM(i); float *map2_y = map2_yR.ptr (i); for (int j = label3; j < label4; j++) { Mat vec = (Mat_ (3, 1) << j, i, 1);//AVM全景圖的grid網(wǎng)格坐標(biāo) vec = matrix * (vec);//獲取鳥瞰圖坐標(biāo) Mat coor = Homo_inverse * vec;//從鳥瞰圖反向投影到去畸變圖 map2_x[j] = coor.at (0, 0); map2_y[j] = coor.at (1, 0); } } //map1(畸變) remap map2(投影+旋轉(zhuǎn)) remap(map1_y, my, map2_xR, map2_yR, INTER_LINEAR); remap(map1_x, mx, map2_xR, map2_yR, INTER_LINEAR); //畸變+投影+旋轉(zhuǎn)+finetune if (finetune) { remap(mx, mx, m_finetune_l_blendX, m_finetune_l_blendY, INTER_LINEAR, BORDER_REPLICATE); remap(my, my, m_finetune_l_blendX, m_finetune_l_blendY, INTER_LINEAR, BORDER_REPLICATE); }
2D AVM Pipeline
9.2 3D AVM
3D AVM Pipeline
04其他
另外還有一種做法:通過廠家提供的相機(jī)安裝參數(shù)計(jì)算魚眼相機(jī)與同意坐標(biāo)系(汽車中心)之間的外參,通過外參將3d模型上的頂點(diǎn)坐標(biāo)轉(zhuǎn)換到相機(jī)坐標(biāo)系下,再通過相機(jī)內(nèi)參轉(zhuǎn)換到圖像坐標(biāo)系上。用此方法同樣可以得到2d圖像紋理與3d模型頂點(diǎn)之間的一一映射關(guān)系。這兩種方法的基本思想其實(shí)是相通的,殊途同歸。只不過這種方法相機(jī)安裝參數(shù)會(huì)有一些誤差,可能會(huì)導(dǎo)致最終的3d拼接效果不佳。
05總結(jié)
AVM2D、3D全景環(huán)視是一個(gè)需要算法理論和實(shí)踐強(qiáng)結(jié)合的自動(dòng)駕駛系統(tǒng),其中涉及到的領(lǐng)域?yàn)橛?jì)算機(jī)視覺、圖像增強(qiáng)、三維等。后續(xù)作者還會(huì)對(duì)標(biāo)定、去畸變等算子進(jìn)行優(yōu)化,并加入自標(biāo)定、車輪視角、廣角、透明底盤等內(nèi)容。
本文的每個(gè)章節(jié)都是首先講述基礎(chǔ)理論,再結(jié)合實(shí)驗(yàn)demo來(lái)進(jìn)行呈現(xiàn),盡量避免繁瑣的公式推導(dǎo),目的在于將AVM系統(tǒng)算法框架搭建的方法講述清楚。如果有不清楚或者哪里說的不夠嚴(yán)謹(jǐn),歡迎大家一起交流進(jìn)步。
-
代碼
+關(guān)注
關(guān)注
30文章
4779瀏覽量
68521 -
計(jì)算機(jī)視覺
+關(guān)注
關(guān)注
8文章
1698瀏覽量
45974 -
AVM
+關(guān)注
關(guān)注
0文章
12瀏覽量
10714
原文標(biāo)題:深度解析自動(dòng)泊車AVM算法框架
文章出處:【微信號(hào):談思實(shí)驗(yàn)室,微信公眾號(hào):談思實(shí)驗(yàn)室】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論