干貨|計(jì)算機(jī)視覺-相機(jī)內(nèi)參數(shù)和外參數(shù)
可能還有很多朋友對機(jī)器視覺中的相機(jī)內(nèi)外參數(shù)不了解,下面就跟著智通培訓(xùn)一塊來了解吧。
1、相機(jī)內(nèi)參數(shù)是與相機(jī)自身特性相關(guān)的參數(shù),比如相機(jī)的焦距、像素大小等;相機(jī)外參數(shù)是在世界坐標(biāo)系中的參數(shù),比如相機(jī)的位置、旋轉(zhuǎn)方向等。
相機(jī)標(biāo)定(或攝像機(jī)標(biāo)定):
一句話就是世界坐標(biāo)到像素坐標(biāo)的映射,當(dāng)然這個(gè)世界坐標(biāo)是我們?nèi)藶槿ザx的,標(biāo)定就是已知標(biāo)定控制點(diǎn)的世界坐標(biāo)和像素坐標(biāo)我們?nèi)ソ馑氵@個(gè)映射關(guān)系,一旦這個(gè)關(guān)系解算出來了我們就可以由點(diǎn)的像素坐標(biāo)去反推它的世界坐標(biāo),當(dāng)然有了這個(gè)世界坐標(biāo),我們就可以進(jìn)行測量等其他后續(xù)操作了~上述標(biāo)定又被稱作隱參數(shù)標(biāo)定,因?yàn)樗鼪]有單獨(dú)求出相機(jī)的內(nèi)部參數(shù),如相機(jī)焦慮,相機(jī)畸變系數(shù)等~一般來說如果你僅僅只是利用相機(jī)標(biāo)定來進(jìn)行一些比較簡單的視覺測量的話,那么就沒有必要單獨(dú)標(biāo)定出相機(jī)的內(nèi)部參數(shù)了~至于相機(jī)內(nèi)部參數(shù)如何解算,相關(guān)論文講的很多~
在圖像測量過程以及機(jī)器視覺應(yīng)用中,為確定空間物體表面某點(diǎn)的三維幾何位置與其在圖像中對應(yīng)點(diǎn)之間的相互關(guān)系,必須建立相機(jī)成像的幾何模型,這些幾何模型參數(shù)就是相機(jī)參數(shù)。在大多數(shù)條件下這些參數(shù)必須通過實(shí)驗(yàn)與計(jì)算才能得到,這個(gè)求解參數(shù)的過程就稱之為相機(jī)標(biāo)定(或攝像機(jī)標(biāo)定)
相機(jī)標(biāo)定的目的是確定相機(jī)的一些參數(shù)的值。通常,這些參數(shù)可以建立定標(biāo)板確定的三維坐標(biāo)系和相機(jī)圖像坐標(biāo)系的映射關(guān)系,換句話說,你可以用這些參數(shù)把一個(gè)三維空間中的點(diǎn)映射到圖像空間,或者反過來。
相機(jī)需要標(biāo)定的參數(shù)通常分為內(nèi)參和外參兩部分。外參確定了相機(jī)在某個(gè)三維空間中的位置和朝向,至于內(nèi)參,可以說是相機(jī)內(nèi)部的參數(shù)(這好像是廢話...笑),我覺得需要引入一點(diǎn)光學(xué)的東西來更好地解釋一下?,F(xiàn)有的相機(jī)都至少包含一個(gè)光學(xué)鏡頭和一個(gè)光電傳感器(CCD或CMOS)。
通過鏡頭,一個(gè)三維空間中的物體經(jīng)常會(huì)被映射成一個(gè)倒立縮小的像(當(dāng)然顯微鏡是放大的,不過常用的相機(jī)都是縮小的),被傳感器感知到。
-
理想情況下,鏡頭的光軸(就是通過鏡頭中心垂直于傳感器平面的直線)應(yīng)該是穿過圖像的正中間的,但是,實(shí)際由于安裝精度的問題,總是存在誤差,這種誤差需要用內(nèi)參來描述;
-
理想情況下,相機(jī)對x方向和y方向的尺寸的縮小比例是一樣的,但實(shí)際上,鏡頭如果不是完美的圓,傳感器上的像素如果不是完美的緊密排列的正方形,都可能會(huì)導(dǎo)致這兩個(gè)方向的縮小比例不一致。內(nèi)參中包含兩個(gè)參數(shù)可以描述這兩個(gè)方向的縮放比例,不僅可以將用像素?cái)?shù)量來衡量的長度轉(zhuǎn)換成三維空間中的用其它單位(比如米)來衡量的長度,也可以表示在x和y方向的尺度變換的不一致性;
-
理想情況下,鏡頭會(huì)將一個(gè)三維空間中的直線也映射成直線(即射影變換),但實(shí)際上,鏡頭無法這么完美,通過鏡頭映射之后,直線會(huì)變彎,所以需要相機(jī)的畸變參數(shù)來描述這種變形效果。
1).外參數(shù)矩陣。告訴你現(xiàn)實(shí)世界點(diǎn)(世界坐標(biāo))是怎樣經(jīng)過旋轉(zhuǎn)和平移,然后落到另一個(gè)現(xiàn)實(shí)世界點(diǎn)(攝像機(jī)坐標(biāo))上。
2).內(nèi)參數(shù)矩陣。告訴你上述那個(gè)點(diǎn)在1的基礎(chǔ)上,是如何繼續(xù)經(jīng)過攝像機(jī)的鏡頭、并通過針孔成像和電子轉(zhuǎn)化而成為像素點(diǎn)的。
3).畸變矩陣。告訴你為什么上面那個(gè)像素點(diǎn)并沒有落在理論計(jì)算該落在的位置上,還tm產(chǎn)生了一定的偏移和變形!??!
2、攝像機(jī)內(nèi)參、外參矩陣
在opencv的3D重建中(opencv中文網(wǎng)站中:照相機(jī)定標(biāo)與三維場景重建),對攝像機(jī)的內(nèi)參外參有講解:
外參:攝像機(jī)的旋轉(zhuǎn)平移屬于外參,用于描述相機(jī)在靜態(tài)場景下相機(jī)的運(yùn)動(dòng),或者在相機(jī)固定時(shí),運(yùn)動(dòng)物體的剛性運(yùn)動(dòng)。因此,在圖像拼接或者三維重建中,就需要使用外參來求幾幅圖像之間的相對運(yùn)動(dòng),從而將其注冊到同一個(gè)坐標(biāo)系下面來
內(nèi)參:下面給出了內(nèi)參矩陣,需要注意的是,真實(shí)的鏡頭還會(huì)有徑向和切向畸變,而這些畸變是屬于相機(jī)的內(nèi)參的。
攝像機(jī)內(nèi)參矩陣:
其中,fx,fy為焦距,一般情況下,二者相等,x0、y0為主點(diǎn)坐標(biāo)(相對于成像平面),s為坐標(biāo)軸傾斜參數(shù),理想情況下為0
攝像機(jī)外參矩陣:包括旋轉(zhuǎn)矩陣和平移矩陣
旋轉(zhuǎn)矩陣和平移矩陣共同描述了如何把點(diǎn)從世界坐標(biāo)系轉(zhuǎn)換到攝像機(jī)坐標(biāo)系
旋轉(zhuǎn)矩陣:描述了世界坐標(biāo)系的坐標(biāo)軸相對于攝像機(jī)坐標(biāo)軸的方向
平移矩陣:描述了在攝像機(jī)坐標(biāo)系下,空間原點(diǎn)的位置
例:
33d
<leftCameraMatrix type_id="opencv-matrix">
<rows>3</rows><cols>3</cols><dt>d</dt>
<data>
7.3582167224957209e+002 0.
1.5950000000000000e+002
0. 7.3582167224957209e+002
1.1950000000000000e+002
0. 0.
1.
</data></leftCameraMatrix>
二、 一些疑問
Q1:標(biāo)定時(shí)棋盤格的大小如何設(shè)定,對最后結(jié)果有沒有影響?
A:當(dāng)然有。在標(biāo)定時(shí),需要指定一個(gè)棋盤方格的長度,這個(gè)長度(一般以毫米為單位,如果需要更精確可以設(shè)為0.1毫米量級)與實(shí)際長度相同,標(biāo)定得出的結(jié)果才能用于實(shí)際距離測量。一般如果尺寸設(shè)定準(zhǔn)確的話,通過立體標(biāo)定得出的Translation的向量的第一個(gè)分量Tx的絕對值就是左右攝像頭的中心距。一般可以用這個(gè)來驗(yàn)證立體標(biāo)定的準(zhǔn)確度。比如我設(shè)定的棋盤格大小為270 (27mm)???,最終得出的Tx大小就是602.8 (60.28mm),相當(dāng)精確。
Q2:通過立體標(biāo)定得出的Tx符號為什么是負(fù)的?
A:這個(gè)其實(shí)我也不是很清楚。個(gè)人的解釋是,立體標(biāo)定得出的T向量指向是從右攝像頭指向左攝像頭(也就是Tx為負(fù)),而在OpenCV坐標(biāo)系中,坐標(biāo)的原點(diǎn)是在左攝像頭的。因此,用作校準(zhǔn)的時(shí)候,要把這個(gè)向量的三個(gè)分量符號都要換一下,最后求出的距離才會(huì)是正的。
但是這里還有一個(gè)問題,就是Learning OpenCV中Q的表達(dá)式,第四行第三列元素是-1/Tx,而在具體實(shí)踐中,求出來的實(shí)際值是1/Tx。這里我和maxwellsdemon討論下來的結(jié)果是,估計(jì)書上Q表達(dá)式里的這個(gè)負(fù)號就是為了抵消T向量的反方向所設(shè)的,但在實(shí)際寫OpenCV代碼的過程中,那位朋友卻沒有把這個(gè)負(fù)號加進(jìn)去。(一家之言,求更詳細(xì)的解釋)
Q3:cvFindStereoCorrespondenceBM的輸出結(jié)果好像不是以像素點(diǎn)為單位的視差?
A:在OpenCV2.0中,BM函數(shù)得出的結(jié)果是以16位符號數(shù)的形式的存儲(chǔ)的,出于精度需要,所有的視差在輸出時(shí)都擴(kuò)大了16倍(2^4)。其具體代碼表示如下:
dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*128/d : 0) + 15) >> 4);
可以看到,原始視差在左移8位(256)并且加上一個(gè)修正值之后又右移了4位,最終的結(jié)果就是左移4位
因此,在實(shí)際求距離時(shí),cvReprojectTo3D出來的X/W,Y/W,Z/W都要乘以16 (也就是W除以16),才能得到正確的三維坐標(biāo)信息
Q4:利用雙攝像頭進(jìn)行測距的時(shí)候世界坐標(biāo)的原點(diǎn)究竟在哪里?
A:世界坐標(biāo)系的原點(diǎn)是左攝像頭凸透鏡的光心。
說起這個(gè),就不得不提到針孔模型。如圖3所示,針孔模型是凸透鏡成像的一種簡化模型。當(dāng)物距足夠遠(yuǎn)時(shí)(遠(yuǎn)大于兩倍焦距),凸透鏡成像可以看作是在焦距處的小孔成像。(ref: http://bak1.beareyes.com.cn/2/lib/200110/04/20011004006.htm)
在實(shí)際計(jì)算過程中,為了計(jì)算方便,我們將像平面翻轉(zhuǎn)平移到針孔前,從而得到一種數(shù)學(xué)上更為簡單的等價(jià)形式(方便相似三角形的計(jì)算),如圖4所示。
圖3. 針孔模型
在實(shí)際計(jì)算過程中,為了計(jì)算方便,我們將像平面翻轉(zhuǎn)平移到針孔前,從而得到一種數(shù)學(xué)上更為簡單的等價(jià)形式(方便相似三角形的計(jì)算),如圖4所示。
圖4. 針孔模型的數(shù)學(xué)等價(jià)形式
因此,對應(yīng)圖2就可以知道,世界坐標(biāo)系原點(diǎn)就是左攝像頭針孔模型的針孔,也就是左攝像頭凸透鏡的光心
Q5:f和d的單位是像素,那這個(gè)像素到底表示什么,它與毫米之間又是怎樣換算的?
A:這個(gè)問題也與針孔模型相關(guān)。在針孔模型中,光線穿過針孔(也就是凸透鏡中心)在焦距處上成像,因此,圖3的像平面就是攝像頭的CCD傳感器的表面。每個(gè)CCD傳感器都有一定的尺寸,也有一定的分辨率,這個(gè)就確定了毫米與像素點(diǎn)之間的轉(zhuǎn)換關(guān)系。舉個(gè)例子,CCD的尺寸是8mm X 6mm,分辨率是640X480,那么毫米與像素點(diǎn)之間的轉(zhuǎn)換關(guān)系就是80pixel/mm。
在實(shí)際運(yùn)用中,我們在數(shù)學(xué)上將這個(gè)像平面等效到小孔前(圖4),這樣就相當(dāng)于將在透鏡中心點(diǎn)之前假設(shè)了一塊虛擬的CCD傳感器。
Q6:為什么cvStereoRectify求出的Q矩陣cx, cy, f都與原來的不同?
A:這個(gè)在前文有提到過。在實(shí)際測量中,由于攝像頭擺放的關(guān)系,左右攝像頭的f, cx, cy都是不相同的。而為了使左右視圖達(dá)到完全平行對準(zhǔn)的理想形式從而達(dá)到數(shù)學(xué)上運(yùn)算的方便,立體 校準(zhǔn)所做的工作事實(shí)上就是在左右像重合區(qū)域最大的情況下,讓兩個(gè)攝像頭光軸的前向平行,并且讓左右攝像頭的f, cx, cy相同。因此,Q矩陣中的值與兩個(gè)instrinsic矩陣的值不一樣就可以理解了。