Camera Calibration(相機校正)
為甚麼需要Camera Calibration ?
- 因為拍出來的影像有形變,形變常見是(圖1.a) radial distortion 又稱為為桶狀形變 barrel distortion 與(圖1.b) tangent distortion 又稱為枕狀形變 pincushion distortion 這兩種,所以才需要把拍出來的影像校正回矩形。
圖1 (a) radial distortion (b)tangent distortion
外部參數
- 因此需要一個矩陣來校正形變,我們稱作這矩陣為相機的「外部參數」,用M來表示作用為將世界座標轉換為以鏡心為原點的座標, 有旋轉矩陣( r1、r2 )和位移矩陣( t ),與像機位置有關。

- EQ 1
內部參數
由圖2可以知道當我們拍攝一個物體時,對CCD sensor 而言,是把一個3D的物體project 到2D的平面上,也就是映射成一格一格的pixel ,因此需要一個矩陣把3D的資訊映射到2D,我們把這個矩陣稱作稱作相機的「內部參數」,我們用A來表示,內部參數中的 α=f/dx,β=f/dy,因为像素不是規規矩矩的正方形,γ代表像素點在x方向和 y方向上尺度的偏差,u0 和 v0 是 是圖像中心(光軸與圖像平麵的交點)坐標,由針孔成像(pin hole model)形成,作用是以相機鏡頭鏡心當作針孔,做針孔成像的轉換,與相機位置無關,但內部參數會隨著焦點不同而改變。

- 圖2 3D object project to 2D image

- EQ 2
影像校正
有了內部參數和外部參數之後,可以利用這兩個參數做影像校正,首先一個物體的長寬高用(Xw,Yw,Zw) 表示,根據相機的位置或拍攝的視角產生旋轉或扭曲,因此利用外部參數M將(Xw,Yw,Zw)轉換成相機座標(Xc,Yc,Zc) ,再經過內部參數A,把相機座標(Xc,Yc,Zc)轉換成平面圖像座標(x,y),根據物體的顏色或亮度等資訊都會被儲存在像素(pixel)中。

- 圖3. 座標轉換流程圖
我們可以用數學來表示這張流程圖
- EQ 3
張正友標定
"張正友標定”又稱“張氏標定”,是指張正友教授於1998年提出的單平面棋盤格的攝像機標定方法。張氏標定法已經作為工具箱或封裝好的函數被廣泛應用。張氏標定的原文為“A Flexible New Technique forCamera Calibration”。此文中所提到的方法,為相機標定提供了很大便利,並且具有很高的精度。從此標定可以不需要特殊的標定物,只需要一張打印出來的「棋盤格」
- 圖4 棋盤格校正
那我們就是要利用張正友標定法利用期盤格來反推相機的內部參數與外部參數,根據 EQ 3 我們令內參乘上外參的矩陣為 homography matrix H ,因此可以表示成 EQ 4 (備註: EQ 4~6中的M為內部參數 也就是EQ 3的 A)

EQ 4
因為 r 1 和 r 2 為 互相垂直的正交基底(orthogonal basis)且為單範正交基底(orthonormal basis),所以r 1 和 r 2的內積為 0 且向量長度均相同為 1,我們令了一個 B 矩陣,只是為了推導和觀察方便,如 EQ 5

- EQ 5
經過 EQ 5 運算後,求得B矩陣是一個對稱矩陣,再帶回EQ 5 的第三條式子 如EQ 6 ,而張正友標定法就是令vb = 0,並使用一系列影像, 假設此依系列有 N 張影像, 則我們可以得到 N 個 vb = 0,因此可以解出B 矩陣,進而得知 fx fy Cx Cy 參數,換言之 A(內部參數) 矩陣就變已知,又可以把外部參數算出來。

- EQ 6
自己動手做(運用 opencv3.0)
首先我列印了15張不同角度的棋盤格(圖5),當作校正的模板。

- 圖 5 棋盤格
我用visual studio 的MFC,設計一˙個很簡單的人機介面(圖 6) ,透過上列的棋盤格,把相機的內部參數和外部參數(旋轉+ 形變)都求出來,最後再校正棋盤格到底哪個方向才是正的。
- 圖6 人機介面
首先是棋盤格的角點(imagecorner)針測
*
https://www.youtube.com/watch?v=f2wd0nfoaOI
為了更準確的抓出角點,運用這個函式 cvFindCornerSubPix 使抓到角點(imagecorner)的精細度提高到小數位
*
https://www.youtube.com/watch?v=yG-d2WQC8Vk
這些抓出來的角點(imagecorner)就是要和實體棋盤格上的角點(objectPoints)做校正,運用函式calibrateCamera可以得到內部參數、外部參數(旋轉+扭曲)
*
https://www.youtube.com/watch?v=ZyPSkf7OCpw
*
https://www.youtube.com/watch?v=KIUS5wTsOrU
*
https://www.youtube.com/watch?v=l6I72yp5uOY
最後是在棋盤格上畫上座標軸,利用剛剛算出的這些參數,把棋盤格上(0,0,0)、(1,0,0)、(0,1,0)、(0,0,1)四個點映射image上,再畫出線
*
https://www.youtube.com/watch?v=TBWmcOnB7Xc
參考資料(Reference)
https://cvg.ethz.ch/teaching/cvl/2012/Tutorial-OpenCV.pdf
http://wycwang.blogspot.tw/2012/10/camera-calibration-part-2-calibration.html
http://blog.csdn.net/onthewaysuccess/article/details/40716731
http://www.autooo.net/utf8-classid105-id82437.html
http://baike.baidu.com/view/1635690.htm