opencv相機標定的一些函式講解
阿新 • • 發佈:2019-01-10
畸變矯正是上一篇博文的遺留問題,當畸變係數和內外引數矩陣標定完成後,就應該進行畸變的矯正,以達到消除畸變的目的,此其一。
是用來標定一個立體攝像頭的,也就是同時標定兩個攝像頭。標定的結果除了能夠求出兩個攝像頭的內外引數矩陣,跟能夠得出兩個攝像頭的位置關係R,T。
在該系列第一部分的博文中介紹的立體成像原理中提到,要通過兩幅影象估計物點的深度資訊,就必須在兩幅影象中準確的匹配到同一物點,這樣才能根據該物點在兩幅影象中的位置關係,計算物體深度。為了降低匹配的計算量,兩個攝像頭的成像平面應處於同一平面。但是,單單依靠嚴格的擺放攝像頭來達到這個目的顯然有些困難。立體校正就是利用幾何圖形變換(Geometric Image Transformation)關係,使得原先不滿足上述位置關係的兩幅影象滿足該條件,此其二。
數學原理
- 畸變矯正(compensate lens distortion)
畸變矯正的方法就是用上一篇博文給出的公式對畫素位置進行重新對映。這裡重新寫出重新對映的公式。
先矯正徑向畸變,
再矯正切向畸變,
- 立體矯正(stereo rectify)
立體矯正能夠有效降低立體匹配的計算量,立體矯正的具體作用見下圖,
立體矯正前,
立體矯正後,
立體矯正的演算法原理沒有詳細瞭解,此處從略。
OpenCV相關函式說明
- 畸變矯正函式 undistort()
undistort() 是獨立的一個畸變矯正函式,一次性可以完成對映矩陣的求解和重新對映。下面我們還會看到把這兩步分開來做的函式。
呼叫方法,
- src-輸入未經過矯正的影象
- dst-經過矯正後輸出的影象
- cameraMatrix-標定而得到的攝像機矩陣
- distCoeffs-標定得到的攝像機畸變矩陣
- newCameraMatrix-輸入矯正後的攝像機矩陣(可以省略)
- 立體標定函式 stereoCalibrate()
stereoCalibrate()
呼叫方法,
double stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1,
InputArrayOfArrays imagePoints2, InputOutputArray cameraMatrix1,InputOutputArray distCoeffs1,
InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2, Size imageSize, OutputArray R, OutputArray T, OutputArray E, OutputArray F, TermCriteria criteria= TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6), int flags=CALIB_FIX_INTRINSIC )
- objectPoints- vector<point3f> 型的資料結構,儲存標定角點在世界座標系中的位置
- imagePoints1- vector<vector<point2f>> 型的資料結構,儲存標定角點在第一個攝像機下的投影后的亞畫素座標
- imagePoints2- vector<vector<point2f>> 型的資料結構,儲存標定角點在第二個攝像機下的投影后的亞畫素座標
- cameraMatrix1-輸入/輸出型的第一個攝像機的相機矩陣。如果
CV_CALIB_USE_INTRINSIC_GUESS , CV_CALIB_FIX_ASPECT_RATIO ,CV_CALIB_FIX_INTRINSIC , or CV_CALIB_FIX_FOCAL_LENGTH
其中的一個或多個標誌被設定,該攝像機矩陣的一些或全部引數需要被初始化 - distCoeffs1-第一個攝像機的輸入/輸出型畸變向量。根據矯正模型的不同,輸出向量長度由標誌決定
- cameraMatrix2-輸入/輸出型的第二個攝像機的相機矩陣。引數意義同第一個相機矩陣相似
- distCoeffs2-第一個攝像機的輸入/輸出型畸變向量。根據矯正模型的不同,輸出向量長度由標誌決定
- imageSize-影象的大小
- R-輸出型,第一和第二個攝像機之間的旋轉矩陣
- T-輸出型,第一和第二個攝像機之間的平移矩陣
- E-輸出型,基本矩陣
- F-輸出型,基礎矩陣
- term_crit-迭代優化的終止條件
-
flag-
- CV_CALIB_FIX_INTRINSIC 如果該標誌被設定,那麼就會固定輸入的cameraMatrix和distCoeffs不變,只求解 $R,T,E,F$R,T,E,F $.
- CV_CALIB_USE_INTRINSIC_GUESS 根據使用者提供的cameraMatrix和distCoeffs為初始值開始迭代
- CV_CALIB_FIX_PRINCIPAL_POINT 迭代過程中不會改變主點的位置
- CV_CALIB_FIX_FOCAL_LENGTH 迭代過程中不會改變焦距
- CV_CALIB_SAME_FOCAL_LENGTH 強制保持兩個攝像機的焦距相同
- CV_CALIB_ZERO_TANGENT_DIST 切向畸變保持為零
- CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6 迭代過程中不改變相應的值。如果設定了 CV_CALIB_USE_INTRINSIC_GUESS 將會使用使用者提供的初始值,否則設定為零
- CV_CALIB_RATIONAL_MODEL 畸變模型的選擇,如果設定了該引數,將會使用更精確的畸變模型,distCoeffs的長度就會變成8
- 立體校正函式 stereoRectify()
stereoRectify() 的作用是為每個攝像頭計算立體校正的對映矩陣。所以其執行結果並不是直接將圖片進行立體矯正,而是得出進行立體矯正所需要的對映矩陣。
呼叫方法,
void stereoRectify(InputArray cameraMatrix1, InputArray distCoeffs1, InputArray cameraMatrix2,InputArray distCoeffs2, Size imageSize, InputArray R, InputArray T,OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags=CALIB_ZERO_DISPARITY, double alpha=-1,
Size newImageSize=Size(), Rect* validPixROI1=0, Rect* validPixROI2=0 )
- cameraMatrix1-第一個攝像機的攝像機矩陣
- distCoeffs1-第一個攝像機的畸變向量
- cameraMatrix2-第二個攝像機的攝像機矩陣
- distCoeffs1-第二個攝像機的畸變向量
- imageSize-影象大小
- R- stereoCalibrate() 求得的R矩陣
- T- stereoCalibrate() 求得的T矩陣
- R1-輸出矩陣,第一個攝像機的校正變換矩陣(旋轉變換)
- R2-輸出矩陣,第二個攝像機的校正變換矩陣(旋轉矩陣)
- P1-輸出矩陣,第一個攝像機在新座標系下的投影矩陣
- P2-輸出矩陣,第二個攝像機在想座標系下的投影矩陣
- Q-4*4的深度差異對映矩陣
- flags-可選的標誌有兩種零或者 CV_CALIB_ZERO_DISPARITY ,如果設定 CV_CALIB_ZERO_DISPARITY 的話,該函式會讓兩幅校正後的影象的主點有相同的畫素座標。否則該函式會水平或垂直的移動影象,以使得其有用的範圍最大
- alpha-拉伸引數。如果設定為負或忽略,將不進行拉伸。如果設定為0,那麼校正後影象只有有效的部分會被顯示(沒有黑色的部分),如果設定為1,那麼就會顯示整個影象。設定為0~1之間的某個值,其效果也居於兩者之間。
- newImageSize-校正後的影象解析度,預設為原解析度大小。
- validPixROI1-可選的輸出引數,
Rect
型資料。其內部的所有畫素都有效 - validPixROI2-可選的輸出引數,
Rect
型資料。其內部的所有畫素都有效
- 對映變換計算函式 initUndistortRectifyMap()
該函式功能是計算畸變矯正和立體校正的對映變換。
呼叫方法,
void initUndistortRectifyMap(InputArray cameraMatrix, InputArray distCoeffs, InputArray R,InputArray newCameraMatrix, Size size, int m1type, OutputArray map1, OutputArray map2)
- cameraMatrix-攝像機引數矩陣
- distCoeffs-畸變引數矩陣
- R- stereoCalibrate() 求得的R矩陣
- newCameraMatrix-矯正後的攝像機矩陣(可省略)
- Size-沒有矯正影象的解析度
- m1type-第一個輸出對映的資料型別,可以為 CV_32FC1 或 CV_16SC2
- map1-輸出的第一個對映變換
- map2-輸出的第二個對映變換
- 幾何變換函式 remap()
呼叫方法,
void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation,int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
- src-原影象
- dst-幾何變換後的影象
- map1-第一個對映,無論是點(x,y)或者單純x的值都需要是
CV_16SC2
,CV_32FC1
, 或CV_32FC2
型別 - map2-第二個對映,y需要是
CV_16UC1
,CV_32FC1
型別。或者當map1是點(x,y)時,map2為空。 - interpolation-插值方法,但是不支援最近鄰插值
- 剩下兩個我也沒看懂,但是一般示例程式中不會設定