簡介
攝像機標定(Camera calibration)簡單來說是從世界坐標系換到圖像坐標系的過程,也就是求最終的投影矩陣 PP 的過程,下面相關的部分主要參考UIUC的計算機視覺的課件(網址Spring 2016 CS543 / ECE549 Computer vision)。
基本的坐標系:
- 世界坐標系(world coordinate system);
- 相機坐標系(camera coordinate system);
- 圖像坐標系(image coordinate system);
一般來說,標定的過程分為兩個部分:
- 第一步是從世界坐標系轉換為相機坐標系,這一步是三維點到三維點的轉換,包括 RR,tt (相機外參)等參數;
- 第二部是從相機坐標系轉為圖像坐標系,這一步是三維點到二維點的轉換,包括 KK(相機內參)等參數;
相機坐標系 轉換到 圖像坐標系
坐標系介紹
如上圖所示(圖片來自UIUC計算機視覺課件),是一個小孔成像的模型,其中:
- CC 點表示
camera centre
,即相機的中心點,也是相機坐標系的中心點; - ZZ 軸表示
principal axis
,即相機的主軸; - pp 點所在的平面表示
image plane
,即相機的像平面,也就是圖片坐標系所在的二維平面; - pp 點表示
principal point
,即主點,主軸與像平面相交的點; - CC 點到 pp 點的距離,也就是右邊圖中的 ff 表示
focal length
,即相機的焦距; - 像平面上的 xx 和 yy 坐標軸是與相機坐標系上的 XX 和 YY 坐標軸互相平行的;
- 相機坐標系是以 XX, YY, ZZ(大寫)三個軸組成的且原點在 CC 點,度量值為米(
m
); - 像平面坐標系是以 xx,yy(小寫)兩個軸組成的且原點在 pp 點,度量值為米(
m
); - 圖像坐標系一般指圖片相對坐標系,在這里可以認為和像平面坐標系在一個平面上,不過原點是在圖片的角上,而且度量值為像素的個數(
pixel
);
相機 轉換到 像平面
知道上面的簡單知識后,如果知道相機坐標系中的一個點 XX(現實三維世界中的點),在像平面坐標系對應的點是 xx,要求求從相機坐標系轉為像平面坐標系的轉換,也就是從 XX 點的(X,Y,Z)(X,Y,Z)通過一定的轉換變為 xx 點的(x,y)(x,y)。注意:(X,Y,Z)(X,Y,Z)(大寫)是在相機坐標系,而(x,y)(x,y)(小寫)是在像平面坐標系(還不是圖像坐標系,原點不同。)觀察第二個圖,很簡單的可以得到這個轉換:
x=fX/Z
y=fY/Zy
(X,Y,Z)↦(fX/Z,fY/Z)
加入偏移量
通過上面,可以把相機坐標系轉換到像平面坐標系,但是像平面坐標系和圖像坐標系雖然在同一個平面上,但是原點並不是同一個,而目標是要轉換到圖像坐標系下,所以還需要一步操作,如下圖:
如上圖所示(圖片來自UIUC計算機視覺課件),其中主點 pp 是像平面坐標系的原點,但在圖像坐標系中的位置為(px,py)(px,py),在這里,圖形坐標系的原點是圖片的左下角,所以可以得到:
(X,Y,Z)↦(fX/Z+px,fY/Z+py)
整理后可以得到 K,也就是平時所說的相機內參(Intrinsic parameters
):
f為焦距,即相機鏡頭光心到成像平面的距離。
像素坐標
前面也提到了在圖像坐標系中用的不是現實生活中的m
來度量,而是用的 pixel
的個數,所以在上面轉換到圖像坐標系中還有個問題,就是坐標的表示還是m
,並沒有轉換到像素坐標系統;在這里需要引入一個新概念就是:
- mx表示在水平方向
1m
的長度包含的像素的個數; - my 表示在豎直方向
1m
的長度包含的像素的個數;
可能有人奇怪為啥不是一個值,還需要分別指定 mxmx 和 mymy 呀,這是因為通過上面可以得到一個像素點的大小(m
度量)為:
但是需要說明的是像素並不一定是一個正方形,有時候可能也是一個矩形,所以要分別指定。
一般來說,在使用相機內參K
計算坐標系轉換時,提供的都是已經變換后的值;例如會提供 fx,fy,cx,cy 四個值代表相機內參K,其實 fx就是這里的 αx,同理 fy 是 αy,cx 是 βx,cy 是 βy。
世界坐標系 轉換到 圖像坐標系
坐標系介紹
如上圖所示(圖片來自UIUC計算機視覺課件),從世界坐標系轉換到相機坐標系是三維空間到三維空間的變換,一般來說需要一個平移操作和一個旋轉操作就可以完成這個轉換,用公式表示如下(可以理解為世界坐標系原點先平移到相機坐標系的位置然后在做一次坐標系旋轉,使坐標軸對齊。):
X~cam=R(X~−C~)
- RR 表示旋轉矩陣;
- X˜X~ 表示 XX 點在世界坐標系中的位置;
- C˜C~ 表示相機原點 CC 在世界坐標系中的位置;
- X˜camX~cam 表示 XX 點在相機坐標系中的位置;
世界 轉換到 相機
根據上面的公式可以得到從一個三維點從世界坐標系轉換到相機坐標的變換公式如下(也是用的齊次坐標的表示方式):
Xcam=(X˜cam1)=[R0−RC˜1](X˜1)=[R0−RC˜1]X
世界 轉換到 圖像
根據上面的討論知道了怎樣從世界坐標系轉換到相機坐標系(平移和旋轉)以及從相機坐標系轉換到圖像坐標系(相機內參變換),所以帶入上面的矩陣計算,可以得到:
x=K[I0]Xcam=K[R−RC˜]X
這樣就得到了最終的投影矩陣 PP :
P=K[Rt]
其中:
t=−RC~
在這里,KK 一般稱為相機內參(intrinsic parameters
),描述了相機的內部參數,包括焦距 ff、主點 pp 的位置、以及像素與真實環境的大小比例等,這個是固有屬性,是提供好的;RR 和 tt 稱為相機外參(extrinsic parameters
),RR 在這里是旋轉矩陣,可以轉換為三維的旋轉向量,分別表示繞xx,yy,zz 三個軸的旋轉角度,tt 目前就是一個平移向量,分別表示在xx,yy,zz 三個方向上的平移量。
畸變參數(distortion parameters
)
在幾何光學和陰極射線管(CRT)顯示中,畸變(distortion
) 是對直線投影(rectilinear projection
)的一種偏移。簡單來說直線投影是場景內的一條直線投影到圖片上也保持為一條直線。那畸變簡單來說就是一條直線投影到圖片上不能保持為一條直線了,這是一種光學畸變(optical aberration
)。可能由於攝像機鏡頭的原因,這里不討論,有興趣的可以查閱光學畸變的相關的資料。
畸變一般可以分為兩大類,包括徑向畸變和切向畸變。主要的一般徑向畸變有時也會有輕微的切向畸變。
徑向畸變(Radial distortion
)
徑向畸變的效應有三種,一種是桶形畸變(barrel distortion
),另一種是枕形畸變(pincushion distortion
),還有一種是兩種的結合叫做胡子畸變(mustache distortion
),從圖片中可以很容易看出區別,具體見下圖(圖片來自wikipedia
):
徑向畸變可以用如下公式修正:
xcorr=xdis(1+k1r2+k2r4+k3r6)
ycorr=ydis(1+k1r2+k2r4+k3r6)
切向畸變(tangential distortion
)
切向畸變是由於透鏡與成像平面不嚴格的平行,其可以用如下公式修正:
xcorr=xdis+[2p1xy+p2(r2+2x2)]
ycorr=ydis+[p1(r2+2y2)+2p2xy]
其中:
- xdisxdis 和 ydisydis 表示有畸變的坐標;
- xcorrxcorr 和 ycorrycorr 表示修復后的坐標;
- k1k1,k2k2,k3k3 表示徑向畸變參數;
- p1p1,p2p2 表示切向畸變參數;
所以最終得到5個畸變參數:
D=(k1,k2,p1,p2,k3)
相機標定
那么可以利用這些來進行最終的任務相機標定,簡單的過程可以描述為通過標定板,如下圖,可以得到n個對應的世界坐標三維點 XiXi 和對應的圖像坐標二維點 xixi,這些三維點到二維點的轉換都可以通過上面提到的相機內參 KK,相機外參 RR和 tt,以及畸變參數 DD 經過一系列的矩陣變換得到。現在就用這些對應關系來求解這些相機參數。最后就是用線性方法求解方程式,這里就不做討論了。
那為什么要做相機標定呢?
每個鏡頭的畸變程度各不相同,通過相機標定可以校正這種鏡頭畸變。其實可以認為用這種標定的方式來求解相機內參和畸變參數,相當於一種相機校准,然后這些參數就可以用於后面的求解。例如求解新拍的兩幅圖片相對的 RR 和 tt,求解這個外參用到就是標定得到的相機內參和畸變參數。
齊次坐標
就是將一個原本是n維的向量用一個n+1維向量來表示。
許多圖形應用涉及到幾何變換,主要包括平移、旋轉、縮放。以矩陣表達式來計算這些變換時,平移是矩陣相加,旋轉和縮放則是矩陣相乘,綜合起來可以表示為 x=R∗X+tx=R∗X+t(注:因為習慣的原因,實際使用時一般使用變化矩陣左乘向量)(RR 旋轉縮放矩陣,tt 為平移矩陣,XX 為原向量,xx 為變換后的向量)。引入齊次坐標的目的主要是合並矩陣運算中的乘法和加法,表示為 x=P∗Xx=P∗X 的形式。即它提供了用矩陣運算把二維、三維甚至高維空間中的一個點集從一個坐標系變換到另一個坐標系的有效方法。和上面的計算過程是對應的。
相機內參詳解
以下是一些個人在工作中對相機內參的學習和理解
首先要了解一下數碼相機的大致成像原理
1.光聚焦在CCD或CMOS上。
2.CCD或CMOS完成光/電轉換。
3.A/D將模擬信號轉換成數字信號。
4.最后由DSP將數字信號轉換成數碼圖像
這里引用《SLAM十四講》中的圖片,圖中物理成像平面可以等同於上面所說的CCD或者CMOS
根據相似三角形關系可以得到:
根據相似三角形關系,我們可以將物體所成的像對稱到相機前方(實際相機中是由相機內部軟件對成像進行倒立像的調節使得我們最后得到正立的像)
在左右兩邊都為 f 的情況下可以得到等大的圖像
則上述公式變為:
根據公式可以知道 歸一化成像平面是怎么定義的,根據對稱得到的虛像
左邊除以 f 右邊除以 f,最后右邊在Z=1的平面上,左邊在f=1的平面得到的圖像
將公式整理可得:
則這個公式表示:
歸一化坐標點,[X/Z,Y/Z,1] 即在Z=1的平面上所成的像和[ X’/f , Y’/f , 1] 即在f=1的成像平面上所得到的像,離開光軸(即原點,Z軸)的距離是相同的,再這個基礎上再乘 f 即可得到,[X, Y, Z]在焦距為f的成像平面上所成的像離開光軸的距離(即成像大小)
所以一般想通過相機坐標得到圖像坐標,首先會將相機坐標歸一化
經過了這個變換,我們就將相機坐標系的坐標(歸一化),投影到了成像平面上。
但是投影到成像平面上之后,在成像平面上的圖像的單位還依舊是長度單位
最后變成我們的像素圖像以像素為單位
那么成像平面到像素平面還會有一層轉換關系,
這一層轉換關系 就是我們所說的 相機內參:
此時我們需要將 長度單位 轉換為 以像素為單位的像素坐標,這個轉換主要由相機內參中的fx與fy來進行確定
物理成像平面其實是由一個個像素單元組成的,每個像素單元就會有 大小,
即這個小單元格像素的寬高,所以 像素單元 的單位是 微米/像素(米,毫米單位並不固定)
舉個例子:
通過投影到成像平面上時
整個圖像長5376μm 寬為 3024μm
最后顯示在1280*720的圖像內 那么每個 物理成像平面每個像素單元的
寬度為 5376/1280 為4.2μm
高度為 3024/720 為4.2 μm
此時像素單元 是正方形的, 此時為 4.2 單位是 μm/像素(若像素單元不是正方形則fx和fy就不同了,所以會存在fx和fy因為大部分都不會是正方形)
根據 opencv中 對於內參 fx與fy的定義:(f是焦距,引用於《學習opencv》–P409)
fx = fsx
fy = fsy
sx的單位是像素/毫米 就是我們上面求得 像素單元size的倒數
轉換一下 可以得到 1/4.2 = 0.238095 像素/μm
(到這基本可以明白如何通過長度轉換為像素了)
這里有個疑問 為什么 fx的定義是 fx = f*sx ?
舉個例子:
假設現在我們有一個世界坐標(相機坐標系) P = [X,Y,Z]
根據小孔成像公式
我們得到坐標 X’ = fX/Z Y’ = fY/Z (成像平面坐標)
但是實際使用矩陣乘法中我們是這樣用
假設內參矩陣時K :
由opencv的定義 fx = f*sx f是焦距 sx單位是像素/μm
那么這個點轉換到像素坐標的為:
Px = K * (P/Z) 即先歸一化在左乘內參矩陣
將乘法分解開來
可以得到 Px = fx*(X/Z) + cx (這里CX是光心 暫不做解釋)
Px = fsx (X/Z) +cx
Px = fsx * (X/Z) = f(X/Z) * sx +cx
所以為什么相機內參會定義為 f*sx就是這個原因
因為坐標在一開始就除以Z進行歸一化了
按照小孔成像公式應該乘f 只不過在opencv中將f移到了內參來進行表達 所以fx和fy的本質是 :
將世界坐標歸一化后的在成像平面上的像(長度單位) 轉換為像素平面上的像素(像素單位)
fx的物理意義: 因為fx 其實 是 f*sx ,sx是像素/μm(該單位並不固定) 加上f之后就變成像素,所以fx的物理意義是 :
在焦距為 f 的成像平面上,每 f 的長度表示多少個像素
最后說明一下CX和CY
在這個圖上可以看到,物理成像平面的中心在光軸上,所以一般在成像平面的中心,但我們最后得到的圖像面試以左上角為原點的像素圖像,所以CX和CY其實是將物理成像平面的原點,做了一個偏移,將以光軸點為原點轉換到以左上角為原點。