本文結合OpenCV官方樣例,對官方樣例中的代碼進行修改,使其能夠正常運行,并對自己采集的數據進行實驗和講解。
一、準備
OpenCV使用棋盤格板進行標定,如下圖所示。為了標定相機,我們需要輸入一系列三維點和它們對應的二維圖像點。在黑白相間的棋盤格上,二維圖像點很容易通過角點檢測找到。而對于真實世界中的三維點呢?由于我們采集中,是將相機放在一個地方,而將棋盤格定標板進行移動變換不同的位置,然后對其進行拍攝。所以我們需要知道(X,Y,Z)的值。但是簡單來說,我們定義棋盤格所在平面為XY平面,即Z=0。對于定標板來說,我們可以知道棋盤格的方塊尺寸,例如30mm,這樣我們就可以把棋盤格上的角點坐標定義為(0,0,0),(30,0,0),(60,0,0),···,這個結果的單位是mm。
3D點稱為object points,2D圖像點稱為image points。

二、檢測棋盤格角點
為了找到棋盤格模板,我們使用openCV中的函數cv2.findChessboardCorners()。我們也需要告訴程序我們使用的模板是什么規格的,例如8*8的棋盤格或者5*5棋盤格等,建議使用x方向和y方向個數不相等的棋盤格模板。下面實驗中,我們使用的是10*7的棋盤格,每個方格邊長是20mm,即含有9*6的內部角點。這個函數如果檢測到模板,會返回對應的角點,并返回true。當然不一定所有的圖像都能找到需要的模板,所以我們可以使用多幅圖像進行定標。除了使用棋盤格,我們還可以使用圓點陣,對應的函數為cv2.findCirclesGrid()。
找到角點后,我們可以使用cv2.cornerSubPix()可以得到更為準確的角點像素坐標。我們也可以使用cv2.drawChessboardCorners()將角點繪制到圖像上顯示。如下圖所示:

三、標定
通過上面的步驟,我們得到了用于標定的三維點和與其對應的圖像上的二維點對。我們使用cv2.calibrateCamera()進行標定,這個函數會返回標定結果、相機的內參數矩陣、畸變系數、旋轉矩陣和平移向量。
四、去畸變
第三步我們已經得到了相機內參和畸變系數,在將圖像去畸變之前,我們還可以使用cv.getOptimalNewCameraMatrix()優化內參數和畸變系數,通過設定自由自由比例因子alpha。當alpha設為0的時候,將會返回一個剪裁過的將去畸變后不想要的像素去掉的內參數和畸變系數;當alpha設為1的時候,將會返回一個包含額外黑色像素點的內參數和畸變系數,并返回一個ROI用于將其剪裁掉。
然后我們就可以使用新得到的內參數矩陣和畸變系數對圖像進行去畸變了。有兩種方法進行去畸變:
新聞熱點
疑難解答