實驗問題
給定若干張圖片,計算畸變係數、內參數矩陣和外參數矩陣。
實驗環境
操作系統:Ubuntu 14.04.3 LTS
開發環境:Anaconda2-4.0.0, OpenCV 2.4.11
實驗過程
相關定義
如今的廉價針孔相機產生了大量的圖像失真。兩個主要的失真是徑向畸變和切向畸變。攝像機標定
由於徑向畸變,直線將出現彎曲。例如,在一張帶有國際象棋的圖像中,兩側邊界不平行。對於這種失真,通過如下公式解決:
類似地,切向畸變產生的原因是攝鏡頭與圖像平面不完全平行對齊。所以圖像中的一些區域可能看起來比預期更接近。它通過如下公式解決:
簡而言之,我們需要找到五個參數,稱爲畸變係數(Distortion cofficients):
此外,我們需要找到更多的信息,比如攝像機的內參數和外參數。內參數是與一臺特定的相機相關的參數,它包括如焦距
外參數對應於轉化一個三維點座標到一個座標系統的旋轉和平移向量。
要查找這些參數,我們要做的是提供一些提前定義好的樣本圖像(如棋盤),然後找到某些特定的點(如在國際象棋棋盤的方角)與現實世界的空間座標的對應關係。我們稱這個操作爲攝像機標定。
算法實現
輸入一系列的棋盤圖片,輸出相應的畸變係數、內參數矩陣和外參數矩陣。步驟如下:
讀取輸入圖片
讀入一系列棋盤圖片。
查找棋盤角落點
使用cv2.findChessboardCorners()
即可找到棋盤的角落點(corner)。
增加角落點的準確性
使用cv2.cornerSubPix()
即可增加角落點的準確性。
繪製角落點
使用cv2.drawChessboardCorners()
繪製角落點。
標定(calibration)
使用cv2.calibrateCamera()
進行標定。
輸入一個標定圖案(這裏是棋盤)的多個不同視角,找到相機的內參數和外參數及畸變係數。算法使用張正友標定方法。
算法主要步驟如下:
初始化內參數和畸變係數。
給定內參數,估計相機的初始姿態。
運行全局的Levenberg-Marquardt優化算法來最小化重投影誤差,即最小化觀測特徵點與投影點的之間的距離平方和。
校正(undistortion)
對每一張輸入的圖像進行校正。首先使用cv2.getOptimalNewCameraMatrix()
進行參數精煉,然後使用cv2.undistort()
進行圖像校正。
實驗數據集
這裏使用opencv提供的一系列棋盤圖片:https://github.com/Itseez/opencv/tree/master/samples/data/left*.jpg 。
每張圖像大小均爲
實驗結果
輸出的畸變係數、內參數矩陣和外參數矩陣如下:
camera matrix:
[[ 532.80990767 0. 342.49522241]
[ 0. 532.93344825 233.88792572]
[ 0. 0. 1. ]]
distortion coefficients:
[ -2.81325825e-01 2.91151890e-02 1.21234424e-03 -1.40823845e-04
1.54861063e-01]
./data/left01.jpg
rotation vector: [ 0.16643477 0.27436631 0.01309966].T
translation vector: [ -3.01603361 -4.3067171 15.89814743].T
./data/left02.jpg
rotation vector: [ 0.41705957 0.65497228 -1.33659106].T
translation vector: [ -2.340185 3.33244685 14.09372759].T
./data/left03.jpg
rotation vector: [-0.27992748 0.18688748 0.3548218 ].T
translation vector: [ -1.59857503 -3.97655053 12.66166695].T
./data/left04.jpg
rotation vector: [-0.114183 0.23776102 -0.00242778].T
translation vector: [ -3.94323477 -2.6513067 13.15766689].T
./data/left05.jpg
rotation vector: [-0.29487152 0.42952325 1.31246259].T
translation vector: [ 2.33553189 -4.5722067 12.63392923].T
./data/left06.jpg
rotation vector: [ 0.4048479 0.30563854 1.64833062].T
translation vector: [ 6.68485875 -2.57792121 13.36792011].T
./data/left07.jpg
rotation vector: [ 0.17465072 0.34620289 1.86816035].T
translation vector: [ 0.7757959 -2.82253787 15.49234179].T
./data/left08.jpg
rotation vector: [-0.09365406 0.48151439 1.75275503].T
translation vector: [ 3.15613747 -3.4776855 12.60232127].T
./data/left09.jpg
rotation vector: [ 0.199544 -0.42539573 0.13303941].T
translation vector: [ -2.65680691 -3.20441687 11.05824157].T
./data/left11.jpg
rotation vector: [-0.42155866 -0.49719158 1.33659792].T
translation vector: [ 1.87146471 -4.39660912 13.45714174].T
./data/left12.jpg
rotation vector: [-0.24157343 0.34844477 1.53044106].T
translation vector: [ 2.02469177 -4.06349774 12.8283411 ].T
./data/left13.jpg
rotation vector: [ 0.46480916 -0.28443331 1.23904774].T
translation vector: [ 1.3442995 -3.61753321 11.56758671].T
./data/left14.jpg
rotation vector: [-0.17318206 -0.46855317 1.3468689 ].T
translation vector: [ 1.79555109 -4.28671937 12.43466065].T
部分圖像校正結果如下圖所示,可以看出,校正之後在現實世界中平行的棋盤線在二維圖像中也平行。
Image after drawChessboardCorners() | Undistorted Image |
---|---|
參考
- Camera Calibration. opencv dev team. 最後修訂於2014年11月10日. http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_calib3d/py_calibration/py_calibration.html ↩
- Zhang Z. A flexible new technique for camera calibration[J]. IEEE Transactions on Pattern Analysis and Machine Intelligence, 2000, 22(11): 1330-1334. ↩