双摄像头立体成像(三)-畸变矫正与立体校正
雙攝像頭立體成像(三)-畸變矯正與立體校正
畸變矯正是上一篇博文的遺留問題,當(dāng)畸變系數(shù)和內(nèi)外參數(shù)矩陣標(biāo)定完成后,就應(yīng)該進(jìn)行畸變的矯正,以達(dá)到消除畸變的目的,此其一。
在該系列第一部分的博文中介紹的立體成像原理中提到,要通過兩幅圖像估計(jì)物點(diǎn)的深度信息,就必須在兩幅圖像中準(zhǔn)確的匹配到同一物點(diǎn),這樣才能根據(jù)該物點(diǎn)在兩幅圖像中的位置關(guān)系,計(jì)算物體深度。為了降低匹配的計(jì)算量,兩個(gè)攝像頭的成像平面應(yīng)處于同一平面。但是,單單依靠嚴(yán)格的擺放攝像頭來達(dá)到這個(gè)目的顯然有些困難。立體校正就是利用幾何圖形變換(Geometric Image Transformation)關(guān)系,使得原先不滿足上述位置關(guān)系的兩幅圖像滿足該條件,此其二。
數(shù)學(xué)原理
- 畸變矯正(compensate lens distortion)
畸變矯正的方法就是用上一篇博文給出的公式對(duì)像素位置進(jìn)行重新映射。這里重新寫出重新映射的公式。
先矯正徑向畸變,
再矯正切向畸變,
- 立體矯正(stereo rectify)
立體矯正能夠有效降低立體匹配的計(jì)算量,立體矯正的具體作用見下圖,
立體矯正前,
立體矯正后,
立體矯正的算法原理沒有詳細(xì)了解,此處從略。
OpenCV相關(guān)函數(shù)說明
- 畸變矯正函數(shù)?undistort()?
?undistort()?是獨(dú)立的一個(gè)畸變矯正函數(shù),一次性可以完成映射矩陣的求解和重新映射。下面我們還會(huì)看到把這兩步分開來做的函數(shù)。
調(diào)用方法,
?
- 立體標(biāo)定函數(shù)?stereoCalibrate()?
?stereoCalibrate()?是用來標(biāo)定一個(gè)立體攝像頭的,也就是同時(shí)標(biāo)定兩個(gè)攝像頭。標(biāo)定的結(jié)果除了能夠求出兩個(gè)攝像頭的內(nèi)外參數(shù)矩陣,跟能夠得出兩個(gè)攝像頭的位置關(guān)系R,T。
調(diào)用方法,
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), intflags=CALIB_FIX_INTRINSIC )?
flag-
- ?CV_CALIB_FIX_INTRINSIC?如果該標(biāo)志被設(shè)置,那么就會(huì)固定輸入的cameraMatrix和distCoeffs不變,只求解 $R,T,E,F$R,T,E,F $.
- ?CV_CALIB_USE_INTRINSIC_GUESS?根據(jù)用戶提供的cameraMatrix和distCoeffs為初始值開始迭代
- ?CV_CALIB_FIX_PRINCIPAL_POINT?迭代過程中不會(huì)改變主點(diǎn)的位置
- ?CV_CALIB_FIX_FOCAL_LENGTH?迭代過程中不會(huì)改變焦距
- ?CV_CALIB_SAME_FOCAL_LENGTH?強(qiáng)制保持兩個(gè)攝像機(jī)的焦距相同
- ?CV_CALIB_ZERO_TANGENT_DIST?切向畸變保持為零
- ?CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6?迭代過程中不改變相應(yīng)的值。如果設(shè)置了?CV_CALIB_USE_INTRINSIC_GUESS?將會(huì)使用用戶提供的初始值,否則設(shè)置為零
- ?CV_CALIB_RATIONAL_MODEL?畸變模型的選擇,如果設(shè)置了該參數(shù),將會(huì)使用更精確的畸變模型,distCoeffs的長(zhǎng)度就會(huì)變成8
- 立體校正函數(shù)?stereoRectify()?
?stereoRectify()?的作用是為每個(gè)攝像頭計(jì)算立體校正的映射矩陣。所以其運(yùn)行結(jié)果并不是直接將圖片進(jìn)行立體矯正,而是得出進(jìn)行立體矯正所需要的映射矩陣。
調(diào)用方法,
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 )?
- 映射變換計(jì)算函數(shù)?initUndistortRectifyMap()?
該函數(shù)功能是計(jì)算畸變矯正和立體校正的映射變換。
調(diào)用方法,
void initUndistortRectifyMap(InputArray cameraMatrix, InputArray distCoeffs, InputArray R,InputArray newCameraMatrix, Size size, int m1type, OutputArray map1, OutputArray map2)?
- 幾何變換函數(shù)?remap()?
調(diào)用方法,
void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation,int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())?
基于OpenCV的仿真
- 仿真程序
?
子函數(shù)calibrate()和calcChessboardCorners()分別是用來表達(dá)相機(jī)和計(jì)算objectPoints的。函數(shù)體如下,
?View Code?
1 static void calcChessboardCorners(Size boardSize, float squareSize, vector<Point3f>& corners) 2 { 3 corners.resize(0); 4 for (int i = 0; i < boardSize.height; i++) //height和width位置不能顛倒 5 for (int j = 0; j < boardSize.width; j++) 6 { 7 corners.push_back(Point3f(j*squareSize, i*squareSize, 0)); 8 } 9 }?
- 仿真結(jié)果
總結(jié)
以上是生活随笔為你收集整理的双摄像头立体成像(三)-畸变矫正与立体校正的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql显示中文乱码问题解决办法(部分
- 下一篇: 湖北汽车工业学院c语言,第六届C语言程序