本文的內(nèi)容為在上一篇avm的進(jìn)階版,主要講述AVM 3D算法pipeline,一種自研提取角點(diǎn)標(biāo)定方法,汽車(chē)輔助視角。每個(gè)部分都涵蓋了完整的算法理論以及部分代碼,適合有一些計(jì)算機(jī)視覺(jué)基礎(chǔ)的同學(xué),或許可以給相關(guān)方向的同學(xué)做些參考。
一. 一種更優(yōu)的聯(lián)合標(biāo)定方案
1.1 算法原理分析
在前面的工作中,我們調(diào)用opencv函數(shù)findChessboardCorners提取圖像上位于標(biāo)定布中間的棋盤(pán)格角點(diǎn),然后計(jì)算投影矩陣H。在SLAM 14講中[1],計(jì)算H就是求解Ax=0這樣一個(gè)問(wèn)題。其原理就是構(gòu)造一個(gè)最小二乘的形式,用奇異值分解的方式來(lái)計(jì)算一個(gè)誤差最小的解。而為了逼近這個(gè)最小誤差,可能造成除了棋盤(pán)格角點(diǎn)以外的其他像素值的投影誤差很大。換句話(huà)說(shuō),由于棋盤(pán)格角點(diǎn)集中于鳥(niǎo)瞰圖的中心很小的一部分區(qū)域,如果選擇棋盤(pán)格角點(diǎn)進(jìn)行H的計(jì)算,會(huì)導(dǎo)致只有棋盤(pán)格附近的區(qū)域能夠進(jìn)行準(zhǔn)確的投影,遠(yuǎn)離該區(qū)域會(huì)有較大誤差。類(lèi)似于nn的訓(xùn)練數(shù)據(jù)過(guò)于局限,訓(xùn)練的模型過(guò)擬合了。這也就能夠解釋為什么在之前的工作中,我們的鳥(niǎo)瞰圖拼接區(qū)域總是拼不齊,就是因?yàn)槲覀冞x擇的角點(diǎn)遠(yuǎn)離拼接區(qū)域,計(jì)算出的投影矩陣H在拼接區(qū)域的投影誤差太大。
我們開(kāi)發(fā)了一種基于自動(dòng)提取角點(diǎn)算法的汽車(chē)標(biāo)定方法,該方法可以提取標(biāo)定布上拼接區(qū)域黑色方格的角點(diǎn)。如圖所示:
拼接區(qū)域角點(diǎn)提取通過(guò)提取拼接區(qū)域的角點(diǎn)最終獲得的全景鳥(niǎo)瞰圖與前面工作的對(duì)比如下,左側(cè)為以前的工作中提取棋盤(pán)格角點(diǎn)的方法且沒(méi)有使用光流微調(diào),右側(cè)是我們提取拼接區(qū)域角點(diǎn)的拼接結(jié)果。差別就很大。
左:提取棋盤(pán)格角點(diǎn) 右:提取拼接區(qū)域角點(diǎn)再仔細(xì)想想這樣做是很合理的,因?yàn)锳VM產(chǎn)品中最影響駕駛體驗(yàn)的就是拼接區(qū)域的偽影,其他一切都好說(shuō)。標(biāo)定布的測(cè)量誤差會(huì)導(dǎo)致單應(yīng)矩陣計(jì)算不準(zhǔn)確,這一問(wèn)題是無(wú)法避免的,我們選擇拼接區(qū)域的特征點(diǎn)計(jì)算單應(yīng)矩陣,使得拼接區(qū)域的拼接結(jié)果非常準(zhǔn)確。隨之而來(lái)的可能是其他區(qū)域的不準(zhǔn)確,例如貼近車(chē)身周?chē)钠灞P(pán)格區(qū)域,但是這些區(qū)域用戶(hù)并不care,雖然車(chē)身周?chē)鷷?huì)引入些許誤差,但只要車(chē)身與周?chē)h(huán)境的的相對(duì)位置呈現(xiàn)的正確,不會(huì)引起碰撞事故,對(duì)于駕駛員來(lái)講就是OK的。
以上就是為什么我們要開(kāi)發(fā)一種基于自動(dòng)提取角點(diǎn)算法的汽車(chē)標(biāo)定方法。
1.2 基于自動(dòng)提取角點(diǎn)算法的汽車(chē)標(biāo)定方法
標(biāo)定場(chǎng)景對(duì)于標(biāo)定布上的棋盤(pán)格,我們可以使用opencv的角點(diǎn)檢測(cè)函數(shù)findChessboardCorners來(lái)提取,建議讀者自行閱讀該函數(shù)源碼,我們提出的方法的思路就來(lái)源于這個(gè)算法。下面我們來(lái)簡(jiǎn)述我們提取大方格角點(diǎn)的方法:
算法流程:
- 雙峰自適應(yīng)閾值二值化
- 多邊形檢測(cè)
- 四邊形篩選
- 提取四邊形頂點(diǎn)
- 雙峰自適應(yīng)閾值二值化
大體思路為:計(jì)算圖像的亮度直方圖。分別計(jì)算暗區(qū)局部極大值,亮區(qū)局部極大值,即“雙峰”。計(jì)算雙峰亮度的平均值,作為閾值,來(lái)對(duì)圖像做二值化。因此稱(chēng)為“雙峰自適應(yīng)閾值”。
解釋下這樣做的理論基礎(chǔ):標(biāo)定布上的大塊黑色方格被白色布包圍在中間,我們的目的是將標(biāo)定布上的黑色方格與白色布通過(guò)某個(gè)閾值分割開(kāi)。通常白色布的亮度值在直方圖亮部閾值附近,黑色方塊的亮度值在直方圖暗部閾值附近。因此取兩個(gè)亮度峰值取平均,一定可以將黑色方塊與白色標(biāo)定布分開(kāi)。當(dāng)然,光照條件不能過(guò)于惡劣,對(duì)于這一點(diǎn)即便是opencv提取棋盤(pán)格的方法也要限定光照條件。
基于自適應(yīng)閾值的二值化- 多邊形檢測(cè)以及四邊形篩選
約束條件
- 多邊形擬合結(jié)果必須為四邊形,即篩選出二值化圖中的四邊形
- 四邊形面積必須大于某閾值(opencv源碼中這個(gè)超參適用于篩選棋盤(pán)格的,我們要把這個(gè)閾值搞得大一些,用于篩選大方格)
- 相鄰邊長(zhǎng)不可相差過(guò)多
- 選取黑色的四邊形,而不是白色的四邊形
- 限制四邊形分布范圍,即四邊形不能過(guò)于靠近圖像邊緣,具體情況與相機(jī)的位姿相關(guān)
- 使用上述約束條件篩選出大方格的角點(diǎn)。
綜上,使用這種方法提取出的角點(diǎn)分布得更廣泛,且都在鳥(niǎo)瞰圖的分布區(qū)域,因此拼接融合得效果更佳。
二. AVM輔助視角——基于外參的視角變換
本章節(jié)主要講述單應(yīng)矩陣與PNP的原理,以及它們?cè)贏VM輔助視角中的實(shí)際應(yīng)用,附帶部分代碼。
關(guān)鍵詞:?jiǎn)螒?yīng)矩陣、PNP、標(biāo)定、廣角、超廣角、車(chē)輪視角、越野模式
車(chē)載魚(yú)眼相機(jī)可以獲取到范圍非常大的內(nèi)容,但是魚(yú)眼圖像并不能夠在汽車(chē)行駛過(guò)程中給駕駛員提供符合人類(lèi)視覺(jué)習(xí)慣的視頻圖像,這一章節(jié)主要來(lái)講述如何利用魚(yú)眼相機(jī)的圖像信息,來(lái)提供各種輔助視角。
例如:
(1)在進(jìn)出車(chē)位或經(jīng)過(guò)狹小空間時(shí),駕駛員會(huì)更加關(guān)注車(chē)輪位置的內(nèi)容,那么我們需要使用某種算法對(duì)左側(cè)、右側(cè)的魚(yú)眼相機(jī)拍攝到的內(nèi)容進(jìn)行處理,得到“車(chē)輪視角”;
(2)對(duì)于正前方、正后方,我們提供了廣角、超廣角。超廣角由前方魚(yú)眼相機(jī)通過(guò)多次投影變換得到。
(3)左右視角根據(jù)不同的要求,我們提供三種不同的輔助視角
從以上的demo中不難看出,我們是通過(guò)投影變換的方法,將魚(yú)眼相機(jī)的圖像從本身相機(jī)部署的視角,轉(zhuǎn)換為我們想要的視角。例如:對(duì)于車(chē)輪視角的demo,不難看出這個(gè)輔助視角中全部都是左、右兩側(cè)的魚(yú)眼相機(jī)中的內(nèi)容。已知這兩個(gè)魚(yú)眼相機(jī)A和B的位姿為:朝向左右兩側(cè)的地面;而我們實(shí)際想獲取的車(chē)輪視角對(duì)應(yīng)的相機(jī)a和b擺放位姿應(yīng)該為朝向前方偏下,即朝向車(chē)輪的那個(gè)位置,這是兩個(gè)虛擬的相機(jī)。那么如果我們通過(guò)標(biāo)定+PNP的方法計(jì)算出右側(cè)鳥(niǎo)瞰相機(jī)A與右側(cè)虛擬相機(jī)a之間的位姿關(guān)系Rt,進(jìn)一步地計(jì)算出A、a這兩個(gè)不同位姿下拍攝某個(gè)平面(地面)時(shí),他們之間的投影關(guān)系H,就可以將實(shí)際的魚(yú)眼相機(jī)視角A轉(zhuǎn)換為虛擬的車(chē)輪視角a。左側(cè)魚(yú)眼相機(jī)B視角與左側(cè)虛擬車(chē)輪視角b同理。
2.1 單應(yīng)矩陣H的原理
有CV基礎(chǔ)的同學(xué)們大多知道單應(yīng)矩陣表示“一個(gè)平面到另外一個(gè)平面的變換關(guān)系”。這樣的描述是不準(zhǔn)確的,或者如果對(duì)單應(yīng)矩陣僅能說(shuō)出這些,說(shuō)明對(duì)單應(yīng)矩陣的認(rèn)識(shí)是片面的。正確的理解應(yīng)該是:H描述的是在不同位姿下的兩個(gè)相機(jī)cam1,cam2拍攝同一個(gè)平面(例如標(biāo)定板),這個(gè)平面在兩個(gè)相機(jī)成像平面上的成像結(jié)果之間的變換關(guān)系。投影變換模型圖如下。以上這段話(huà),被很多人簡(jiǎn)單理解成了“H描述的是兩張圖象之間的變換關(guān)系”,這里有兩個(gè)點(diǎn)需要注意:(1)不要忽略掉了前面那部分和相機(jī)投影相關(guān)的物理模型(2)H描述的是空間中的某個(gè)平面分別在兩個(gè)相機(jī)圖像平面上的成像結(jié)果之間的變換,而不是兩個(gè)圖像之間的變換。
對(duì)于單應(yīng)矩陣,我們可以思考一個(gè)問(wèn)題:我們拍攝到的內(nèi)容,大多數(shù)情況下不僅僅包含某一個(gè)平面。而我們?cè)谧鐾队白儞Q的時(shí)候,H就是基于某個(gè)平面計(jì)算出來(lái)的,這會(huì)導(dǎo)致雖然圖像中的該平面部分的投影是合理的,但是因?yàn)槠矫嬉酝獾钠渌糠忠廊挥孟嗤腍做投影,這些部分的投影結(jié)果就會(huì)顯得非常的奇怪。
相信很多同學(xué)聽(tīng)說(shuō)過(guò)一個(gè)結(jié)論:基于H的圖像拼接方法,比較適用于視距較遠(yuǎn)的環(huán)境下。這是因?yàn)橐暰噍^遠(yuǎn)的環(huán)境下,拍攝到的景象我們可以近似認(rèn)為它們?cè)谕粋€(gè)平面上,那么我們基于這個(gè)平面計(jì)算出來(lái)的H,就幾乎適用于整個(gè)圖像中的內(nèi)容。
我們從最基礎(chǔ)的相機(jī)物理模型來(lái)推導(dǎo)一遍單應(yīng)矩陣H的公式,這樣有利于我們更深入地理解。(本文僅推導(dǎo)這一個(gè)公式,通過(guò)物理模型對(duì)單應(yīng)矩陣進(jìn)行推導(dǎo)對(duì)后面的算法理解十分重要)
如圖所示,同一個(gè)相機(jī)在A,B兩個(gè)位置以不同的位姿拍攝同一個(gè)平面:
投影變換模型圖中n表示穿過(guò)相機(jī)A的光心垂直于平面π的單位向量,d為相機(jī)A與平面π之間的距離。π平面上的點(diǎn)X分別投影到A、B相機(jī)平面上的m和m'上。X在A相機(jī)坐標(biāo)系下坐標(biāo)為X1,在B坐標(biāo)系下坐標(biāo)為X2。
因此有:
假設(shè)相機(jī)A與B之間的相對(duì)位姿為R t,即旋轉(zhuǎn)和平移,那么有:
根據(jù)相機(jī)成像模型,其中K為相機(jī)內(nèi)參,s1為某像素的實(shí)際深度
因此推導(dǎo)到最后,H結(jié)果為:
由于H有尺度不變性,因此
經(jīng)過(guò)上述推導(dǎo)后我們可以得出結(jié)論:假設(shè)我們可以獲取到兩個(gè)相機(jī)之間的位姿關(guān)系R和t、相機(jī)的內(nèi)參、相機(jī)與π平面之間的向量n和距離d,那么我們就可以計(jì)算出π平面在兩個(gè)相機(jī)圖像平面上的投影關(guān)系H。以上即為單應(yīng)矩陣求解的一種方法(基于真實(shí)的物理模型),也是本章中AVM輔助視角所用到的方法。
那么,如何才能獲取到相機(jī)之間的位姿關(guān)系呢?我們用到了PNP的方法。
2.2 PNP的原理
用一句話(huà)概括PNP到底做了什么:已知相機(jī)A坐標(biāo)系下的一組三維點(diǎn),以及這組三維點(diǎn)在另外一個(gè)相機(jī)的圖像坐標(biāo)系下的二維坐標(biāo),就可以通過(guò)數(shù)學(xué)方法計(jì)算出A、B兩個(gè)相機(jī)之間的位姿R,t。注意R,t是從A->B。
公式如下:
其中(X,Y,Z,1)為某一個(gè)相機(jī)坐標(biāo)系下的三維點(diǎn)齊次坐標(biāo),(u,v)為另一個(gè)相機(jī)圖像平面的二維坐標(biāo)點(diǎn)。這兩組點(diǎn)在真實(shí)世界中應(yīng)該是一一對(duì)應(yīng)的關(guān)系。K為相機(jī)內(nèi)參,Rt為相機(jī)之間的外參。這個(gè)模型其實(shí)就是SLAM14講中的單目相機(jī)物理模型,世界坐標(biāo)系->相機(jī)坐標(biāo)系->圖像坐標(biāo)系的過(guò)程。求解方法有“直接線(xiàn)性法”、“最小化重投影誤差”等,我們就不展開(kāi)來(lái)說(shuō)了。
針對(duì)于我們的AVM算法:
先驗(yàn)信息必然是由標(biāo)定布來(lái)提供的(即第一章中講到的標(biāo)定布上的大方格角點(diǎn)信息,包含圖像上的二維坐標(biāo)和標(biāo)定的三維坐標(biāo))。虛擬相機(jī)的位置、朝向由我們自己設(shè)定,換句話(huà)說(shuō)虛擬相機(jī)坐標(biāo)系是根據(jù)不同功能(例如車(chē)輪視角、超廣角等)由算法工程師自行設(shè)計(jì)的,因此我們是可以獲取到標(biāo)定布上的角點(diǎn)的三維坐標(biāo)。
- 二維點(diǎn):圖像中提取(1.1 1.2中已經(jīng)講述了提取方法)
- 三維點(diǎn):標(biāo)定
2.3 車(chē)輪視角
車(chē)輪視角算法坐標(biāo)系示意圖車(chē)輪視角算法坐標(biāo)系示意圖- 2d圖像坐標(biāo)系沒(méi)什么可說(shuō)的,就是真實(shí)相機(jī)拍攝到的圖像上黑色方格角點(diǎn)的坐標(biāo)
- 3d相機(jī)坐標(biāo)系是一個(gè)虛擬的視角,模擬的是朝向正前方的一個(gè)視角,即y垂直地面,x垂直車(chē)身向右,z朝正前方由于我們已知標(biāo)定布的全部尺寸參數(shù),因此可獲取虛擬相機(jī)坐標(biāo)系下標(biāo)定布上黑色方格角點(diǎn)的3維坐標(biāo)。用PNP算法可以計(jì)算出實(shí)際相機(jī)與虛擬相機(jī)之間的位姿關(guān)系R,t。
**//函數(shù)定義**
voidsolveRtFromPnP(constvector&corners2D,constvector&obj3D,
constMat&intrinsic,Mat&R,Mat&t){
Matr=Mat::zeros(3,1,CV_32FC1);
solvePnP(obj3D,corners2D,intrinsic,cv::Mat(),r,t);
Rodrigues(r,R);
}
//函數(shù)調(diào)用
solveRtFromPnP(corners_2D,obj_3D,m_intrinsic_undis,R,t);
以上,我們獲取到了虛擬相機(jī)->真實(shí)部署相機(jī)之間的位姿R,t。至于R,t為什么不是從真實(shí)部署相機(jī)->虛擬相機(jī),可以從PNP算法的公式推導(dǎo)中得知(前面已經(jīng)講過(guò)),或者見(jiàn)視覺(jué)SLAM第二版P180-P181。
再回到投影變換H模型圖中,圖中的A就是虛擬相機(jī),B就是真實(shí)部署相機(jī)。我們已經(jīng)通過(guò)PNP計(jì)算出虛擬相機(jī)->真實(shí)部署相機(jī)的R,t。但是我們想要的是如何將真實(shí)相機(jī)拍攝到的某個(gè)平面(對(duì)于車(chē)輪視角而言是地面)通過(guò)H轉(zhuǎn)換到虛擬相機(jī)的視角下。因此我們需要對(duì)R,t做一些處理,將其轉(zhuǎn)化為真實(shí)部署相機(jī)->虛擬相機(jī)的位姿關(guān)系:
公式推導(dǎo):
Rt位姿的轉(zhuǎn)換投影關(guān)系的建立代碼:
求解單應(yīng)矩陣:
//基于Rt計(jì)算H
MatsolveHFromRt(constMat&R,constMat&t,constfloatd,constMat&n,constMat&intrinsic){
Matintrinsic_inverse;
invert(intrinsic,intrinsic_inverse,DECOMP_LU);
MatH=intrinsic*(R+t/d*n.t())*intrinsic_inverse;
returnH;
}
PNP求解外參:
/****************************************************************************************************************/
//Rt:PNP算出的結(jié)果,從虛擬相機(jī)->真實(shí)部署相機(jī)的位姿
//計(jì)算出真實(shí)部署相機(jī)->虛擬相機(jī)的位姿
MatR_Camera2Real;
invert(R,R_Real2Virtual,DECOMP_LU);
Matt_Real2Virtual=-R_Real2Virtual*t;
//虛擬相機(jī)到地面的垂直單位向量
Matn=(Mat_<float>(3,1)<0,?1,?0);
??
//真實(shí)部署相機(jī)到地面的垂直單位向量
??
n?=?R?*?n;
??
//?rotation
??
floattheta_X=m_wheel_sight_angle/180.f*3.14f;
MatR_virtual=(Mat_<float>(3,3)<1,?0,?0,?0,?cos(theta_X),?-sin(theta_X),
??
???????????????????0,?sin(theta_X),?cos(theta_X));
??
R_Camera2Virtual?=?R_virtual?*?R_Camera2Virtual;
??
t_Camera2Virtual?=?R_virtual?*?t_Camera2Virtual;
??
//計(jì)算單應(yīng)矩陣H:真實(shí)視角->虛擬視角
MatH=solveHFromRt(R_Camera2Virtual,t_Camera2Virtual,d,n,intrinsic);
幾點(diǎn)說(shuō)明:
- n(0,1,0),說(shuō)明單應(yīng)矩陣選取的平面為地面。不要忘了我們最開(kāi)始強(qiáng)調(diào)的,H描述的是在不同位姿下的兩個(gè)相機(jī)cam1,cam2拍攝同一個(gè)平面(例如標(biāo)定板),這個(gè)平面在兩個(gè)相機(jī)成像平面上的成像結(jié)果之間的變換關(guān)系。因此這個(gè)平面的選擇,對(duì)最終的投影結(jié)果有很大的影響。車(chē)輪視角選取地面作為我們要進(jìn)行投影的平面,最終的效果非常nice。
- 代碼中還包含rotation部分,這是因?yàn)槲覀冊(cè)跇?biāo)定的時(shí)候讓虛擬相機(jī)朝正前方,但顯然理想的車(chē)輪視角相機(jī)應(yīng)該朝向車(chē)輪,即應(yīng)加一個(gè)俯仰角pitch。
2.4 超級(jí)廣角
這部分我們是對(duì)標(biāo)現(xiàn)有某德系車(chē)載超廣角功能進(jìn)行實(shí)現(xiàn)的,相比于直接做去畸變的廣角效果,超廣角的優(yōu)勢(shì)在于
- 糾正了相機(jī)翻滾角帶來(lái)的視覺(jué)不適
- 糾正了左右兩側(cè)遠(yuǎn)離圖像中心的拉伸效果
- 糾正了豎直方向由于透視畸變“近大遠(yuǎn)小”帶來(lái)的柱體傾斜效果
大部分車(chē)上的廣角功能是對(duì)魚(yú)眼圖直接做了去畸變,這種方法帶來(lái)的問(wèn)題及產(chǎn)生原因如下:
- 放大上表中普通廣角圖,不難發(fā)現(xiàn)標(biāo)定布前邊緣并不是平直的,它有一定的傾斜。這是因?yàn)橄鄼C(jī)有一個(gè)roll翻滾角,相當(dāng)于人眼沒(méi)有水平正視前方,而是歪著腦袋看前面。
- 在遠(yuǎn)離圖像中心的位置,像素被嚴(yán)重拉伸,這是透視畸變的一種(見(jiàn)附錄),會(huì)導(dǎo)致即便是我們把去畸變圖的分辨率調(diào)整到非常大,在這張圖像上依然不能看到FOV范圍很大的內(nèi)容,如圖所示。
這張圖的分辨率已經(jīng)很大,然而在圖像的邊緣像素跨度太大,圖中左側(cè)的黑色車(chē)輛被嚴(yán)重拉伸。也就是說(shuō)同樣一輛車(chē),在圖像的中心可能只需要100個(gè)像素來(lái)呈現(xiàn)(例如中間的白車(chē)),而在圖像的邊緣被拉伸的更長(zhǎng),可能需要1000個(gè)像素才能完全呈現(xiàn)出來(lái),如果我們想要獲取更大范圍的視野,就需要超級(jí)大分辨率的圖像。
- 垂直地面的柱子是斜的:這是因?yàn)榱硗庖环N透視畸變(見(jiàn)附錄),即”近大遠(yuǎn)小“。類(lèi)似于平行的車(chē)道線(xiàn)在圖像中會(huì)交于一點(diǎn)的原理。我們可以記住一個(gè)理論:只有垂直于相機(jī)光軸的那個(gè)平面上的平行線(xiàn),在相機(jī)圖像平面上的成像結(jié)果是平行的(類(lèi)似于BEV視角);與光軸不垂直的平面上的平行線(xiàn),在相機(jī)成像平面上肯定交于一點(diǎn),即”近大遠(yuǎn)小”。對(duì)圖像做去畸變之后,圖中的柱子是斜的,因?yàn)槲覀兊那爸脭z像頭有pitch俯仰角,它的光軸超前下方,并非垂直于柱子所在的平面,即不垂直于汽車(chē)正前方的平面。
解決方案:
我們的思路是:首先通過(guò)位姿變換的方法將相機(jī)擺正(依然是虛擬相機(jī)的思想),從而消除“近大遠(yuǎn)小”的透視畸變和相機(jī)roll角帶來(lái)的視覺(jué)不適,然后將圖像分為左、中、右三部分,中間這部分的“拉伸”透視畸變較小;對(duì)兩側(cè)透視畸變較大的部分強(qiáng)制進(jìn)行某種投影變換,減小拉伸效果。具體如下:
- 相機(jī)位姿矯正
相機(jī)位姿矯正算法流程的思路依然是將 真實(shí)相機(jī)視角->虛擬相機(jī)視角,以正前方的相機(jī)為例,算法流程如下表:
算法流程
- 假設(shè)虛擬相機(jī)的位姿為朝向正前方,光軸與正前方的那面墻垂直,坐標(biāo)系x、y、z如上表中“位姿校正的廣角”所示
- 標(biāo)定出地面上那些角點(diǎn)在虛擬相機(jī)坐標(biāo)系下的三維坐標(biāo)
- 在真實(shí)相機(jī)拍攝的圖像中提取角點(diǎn)的圖像坐標(biāo)(實(shí)際上在第一章的標(biāo)定過(guò)程中已經(jīng)完成)
- PNP計(jì)算虛擬相機(jī)->真實(shí)相機(jī)的位姿 RT
- 計(jì)算真實(shí)相機(jī)->虛擬相機(jī)的位姿rt
- 我們選定的是垂直于相機(jī)光軸的平面,計(jì)算這個(gè)平面從真實(shí)相機(jī)->虛擬相機(jī)的單應(yīng)矩陣H,在我們的算法中,這個(gè)平面距離相機(jī)的距離d=10m,這是一個(gè)經(jīng)驗(yàn)值。
這個(gè)流程與上面的車(chē)輪視角的算法流程幾乎是相同的,所有的相機(jī)位姿變換導(dǎo)致的視角轉(zhuǎn)換都可以用這個(gè)流程來(lái)實(shí)現(xiàn)。在上面的相機(jī)位姿矯正示意圖中我們可以看到,垂直于地面的墻、柱子的傾斜問(wèn)題都解決了。被我們用基于相機(jī)位姿矯正的單應(yīng)變換強(qiáng)行掰正了。
但是,這個(gè)圖在遠(yuǎn)離圖像中心的邊緣依然存在嚴(yán)重的拉伸。導(dǎo)致即使圖像的分辨率很大,我們可以看到的實(shí)際FOV范圍依然很小。針對(duì)這個(gè)問(wèn)題,再一次進(jìn)行平面的單應(yīng)變換。
平面單應(yīng)變換
平面單應(yīng)變換示意圖廣角與超廣角實(shí)際的實(shí)現(xiàn)方法如下圖所示,在廣角圖像上選取4個(gè)點(diǎn)(即遠(yuǎn)離圖像中心在圖像左右兩邊的兩個(gè)小長(zhǎng)方形),并設(shè)置這四個(gè)點(diǎn)做投影變換的結(jié)果(這4個(gè)點(diǎn)是通過(guò)大量實(shí)驗(yàn)調(diào)試出的一組最優(yōu)超參數(shù)),使用這四對(duì)匹配點(diǎn)計(jì)算單應(yīng)矩陣H。即計(jì)算將小長(zhǎng)方形壓縮成梯形的單應(yīng)矩陣H。
圖像兩側(cè)的單應(yīng)變換在圖像兩側(cè)所進(jìn)行的單應(yīng)變換有將像素在x,y方向做壓縮的效果,從一定程度上減小了透視畸變帶來(lái)的拉伸問(wèn)題。做了投影變換后,在相同幅面的圖像中,我們可以看到更大范圍的內(nèi)容,即FOV更大,因此稱(chēng)為超廣角。
MatH_left=getPerspectiveTransform(p_src_left,p_dst_left);
MatH_right=getPerspectiveTransform(p_src_right,p_dst_right);
三. 基于外參的3D 紋理映射方法
單目相機(jī)是丟失了深度信息的,計(jì)算機(jī)圖形學(xué)中經(jīng)常會(huì)使用將紋理圖映射到某個(gè)3D模型上的方法,呈現(xiàn)出一種偽3D的效果,即紋理映射。在AVM中,通常使用將相機(jī)捕捉到的圖像當(dāng)作紋理,以某種方式映射到 3D 碗狀模型上以呈現(xiàn)出一種3D 環(huán)視的效果。下面詳細(xì)講述下算法實(shí)現(xiàn):
3.1 3D模型
前、后、左、右3.2 紋理映射
以前置相機(jī)為例,詳細(xì)描述3D模型與相機(jī)圖像之間的紋理映射關(guān)系:
紋理映射示意圖注意:世界坐標(biāo)系、3dsmax坐標(biāo)系、車(chē)身統(tǒng)一坐標(biāo)系,這三個(gè)表達(dá)的是同一個(gè)意思。坐標(biāo)原點(diǎn)在汽車(chē)中心,右手X,汽車(chē)前方Y(jié),垂直地面向上Z。黃色坐標(biāo)軸為前置相機(jī)坐標(biāo)系。
如圖所示,3dsmax中的小長(zhǎng)方體代表現(xiàn)實(shí)世界中在汽車(chē)正前方的柱子。該立柱上的一點(diǎn)(第二張圖上長(zhǎng)方體上的圓圈)通過(guò)相機(jī)成像模型穿過(guò)相機(jī)光心映射到成像平面上(即第一張圖中柱子上的圓圈位置)。在成像過(guò)程中,同時(shí)也要穿越我們的3D碗模型。我們通過(guò)相機(jī)成像模型,可以想象這條光線(xiàn)的路徑:現(xiàn)實(shí)世界中的物體->3D碗模型頂點(diǎn)->相機(jī)拍攝到的圖像(去畸變后),也就是通過(guò)相機(jī)成像模型我們建立起了3D碗模型頂點(diǎn)與圖像紋理之間的映射關(guān)系。
我們通過(guò)3dsmax制作的 3D碗模型是一個(gè)OBJ文件,解析出來(lái)的是3dsmax坐標(biāo)系下的坐標(biāo)。我們需要將其轉(zhuǎn)換到相機(jī)坐標(biāo)系下,才可以進(jìn)行上面說(shuō)的紋理映射。3dsmax是以汽車(chē)的中心為原點(diǎn),右手為X,前向?yàn)閅,垂直地平面向上為Z的,在標(biāo)定過(guò)程中,我們可以獲取上圖中角點(diǎn)在3dsmax坐標(biāo)系下的3維坐標(biāo);且可以在前置相機(jī)圖像中通過(guò)算法提取角點(diǎn)的圖像坐標(biāo),因此3dsmax與相機(jī)之間的位姿關(guān)系,同樣可以通過(guò)PNP計(jì)算。代碼如下:
//calculatepose
solveRtFromPnP(img_corners,obj_corners,intrinsic_undis,R,t);
//3dsmax->camera
Matpts_3DsMax=
(Mat_<float>(3,1)<imgcoordinate
Matcoor=intrinsic_undis*camera_points/camera_points.at<float>(2,0);
上述代碼將解析出來(lái)的3dsmax坐標(biāo)系下的 3d碗模型的頂點(diǎn)三維坐標(biāo)轉(zhuǎn)換到相機(jī)坐標(biāo)系下,然后通過(guò)相機(jī)內(nèi)參轉(zhuǎn)換到圖像坐標(biāo)系。最終建立起3d碗模型與圖像紋理之間的映射關(guān)系。算法流程如下:
算法流程
- 標(biāo)定3dsmax坐標(biāo)系下 標(biāo)定布上角點(diǎn)的三維坐標(biāo)。(即車(chē)身中心為原點(diǎn)的車(chē)身坐標(biāo)系)
- 檢測(cè)相機(jī)拍攝到圖像中標(biāo)定布上角點(diǎn)的圖像坐標(biāo)。(第一章中已標(biāo)定)
- 利用1、2的坐標(biāo)信息,通過(guò)PNP計(jì)算出 3dsmax坐標(biāo)系與相機(jī)坐標(biāo)系之間的位姿關(guān)系 R,t
- 解析3d碗狀模型的obj文件
- 將解析出來(lái)的3d碗狀模型的頂點(diǎn)三維坐標(biāo),通過(guò)R,t轉(zhuǎn)換到相機(jī)坐標(biāo)系下
- 通過(guò)內(nèi)參將相機(jī)坐標(biāo)系的坐標(biāo)轉(zhuǎn)換到圖像坐標(biāo)系,建立起3d模型與相機(jī)圖像之間的紋理映射關(guān)系
3.3 融合
融合區(qū)相鄰兩個(gè)3D 碗模型上存在重疊區(qū),由于標(biāo)定誤差和avm 3d算法固有的誤差,這部分重疊區(qū)域會(huì)有較嚴(yán)重的重影(下一節(jié)中會(huì)講到)。因此需要用融合算法進(jìn)行平滑過(guò)渡。具體算法可以參考文章[2]
融合算法示意圖大體思路就是計(jì)算3d模型上的頂點(diǎn)與縫合線(xiàn)之間的角度,然后求一個(gè)比值,沒(méi)什么太大難度。
3.4 3D AVM算法存在的問(wèn)題
在討論這個(gè)問(wèn)題之前,我們首先要理解相機(jī)坐標(biāo)系。相機(jī)坐標(biāo)系一般x為朝右,y為朝下,z為朝向正前方。圖中標(biāo)記的兩個(gè)坐標(biāo)系分別為汽車(chē)前置攝像頭、左側(cè)攝像頭的位姿。一個(gè)安裝在汽車(chē)前方朝向前下方,一個(gè)安裝在汽車(chē)左側(cè)后視鏡朝向左下方。
AVM 3D病態(tài)問(wèn)題現(xiàn)實(shí)世界中立柱上的一個(gè)點(diǎn)通過(guò)相機(jī)模型分別映射到前置相機(jī)、左側(cè)相機(jī)的成像平面上從而生成圖像img1,img2。在這個(gè)過(guò)程中會(huì)穿過(guò)重疊區(qū)的前3D碗模型的A點(diǎn)以及左3D碗模型的B點(diǎn),AB顯然不是同一個(gè)點(diǎn)。換句話(huà)說(shuō),img1和img2上相同的紋理(例如現(xiàn)實(shí)世界中的柱子)在紋理映射的過(guò)程中并沒(méi)有映射到3d碗模型的同一個(gè)位置上,不能夠準(zhǔn)確地重合,且通常會(huì)在模型重疊區(qū)有較大的錯(cuò)位。
因此,我們可以得出結(jié)論:AVM的3D是一種偽3D,是計(jì)算機(jī)圖形學(xué)中使用將紋理圖映射到3D模型上呈現(xiàn)3D效果的手段,但它不是真正的3D。根本原因是:?jiǎn)文肯鄼C(jī)模型丟失了深度信息。
針對(duì)這種問(wèn)題,通常的優(yōu)化方法為:
- 將拼接縫位置設(shè)置在較不明顯的位置上,例如靠近左右兩側(cè)。因?yàn)轳{駛員開(kāi)車(chē)的視覺(jué)習(xí)慣通常是正前方,左右兩側(cè)的內(nèi)容不會(huì)過(guò)分關(guān)注。且在切換到其他視角的時(shí)候,拼接錯(cuò)位會(huì)被汽車(chē)模型擋住。
- 適當(dāng)縮小拼接區(qū)范圍
- 盡量讓碗底大一些,讓車(chē)身附近的地面有較好的拼接效果。
- 3d碗的優(yōu)化問(wèn)題屬于經(jīng)驗(yàn)性的問(wèn)題,需要通過(guò)實(shí)驗(yàn)慢慢調(diào)整適合自己的碗模型。
四 附錄
透視畸變
- “近大遠(yuǎn)小”
“近大遠(yuǎn)小”表達(dá)的是:同一個(gè)物體,在遠(yuǎn)處的位置投影到相機(jī)平面上的大小要小于在近處的位置。例如,車(chē)道線(xiàn)投影到圖像上并不是平行線(xiàn),會(huì)交于一點(diǎn)。下圖中O為相機(jī)原點(diǎn),Image plane為相機(jī)成像平面,parallel lines為現(xiàn)實(shí)世界中兩條平行線(xiàn)。這兩條平行線(xiàn)投影到image plane上,距離相機(jī)越遠(yuǎn)的位置,其間距投影到image plane上的長(zhǎng)度越短,最后匯聚到一點(diǎn),即“消失點(diǎn)”。這個(gè)現(xiàn)象就類(lèi)似于我們對(duì)圖像做去畸變后,汽車(chē)前方兩個(gè)垂直的柱子在圖像中是斜的,最終會(huì)交于一點(diǎn)。但是如果相機(jī)光軸垂直于地面,車(chē)道線(xiàn)在圖像上的成像結(jié)果就是平行的,類(lèi)似于BEV。所以,我們?cè)谧龀瑥V角功能的時(shí)候,要對(duì)相機(jī)做位姿矯正,使相機(jī)的光軸朝向正前方,這樣得到的圖像結(jié)果中柱子就不會(huì)傾斜。
近大遠(yuǎn)小- “拉伸”
一張圖,言簡(jiǎn)意賅:
邊緣拉伸五 總結(jié)
本篇本章為avm系列的第二篇,至此AVM主要的算法原理已經(jīng)講述完畢,包含有:相機(jī)模型、相機(jī)內(nèi)外參標(biāo)定、相機(jī)聯(lián)合標(biāo)定方法、魚(yú)眼去畸變、投影變換、光流、拼接融合、PNP、3D紋理映射、上帝視角、3d視角、廣角、超廣角、車(chē)輪視角等。
后續(xù)還要做一些其他工作,例如:亮度一致調(diào)整、基于車(chē)道線(xiàn)的道路自標(biāo)定、動(dòng)態(tài)拼接線(xiàn)、相機(jī)模型優(yōu)化等。希望以后還有機(jī)會(huì)和同學(xué)們交流,共同進(jìn)步!
審核編輯 :李倩
-
算法
+關(guān)注
關(guān)注
23文章
4592瀏覽量
92524 -
角點(diǎn)
+關(guān)注
關(guān)注
0文章
3瀏覽量
5903 -
自動(dòng)泊車(chē)
+關(guān)注
關(guān)注
0文章
100瀏覽量
13668
原文標(biāo)題:詳解自動(dòng)泊車(chē)之AVM環(huán)視系統(tǒng)算法(聯(lián)合標(biāo)定/視角變換/紋理映射)
文章出處:【微信號(hào):vision263com,微信公眾號(hào):新機(jī)器視覺(jué)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論