OpenCV中提供了多种双目匹配算法,比如BM,SGBM,HH等,并提供了各算法主要参数的设置与获取方式,加速了双目匹配的算法开发。双目匹配遵循以下的流程:相机标定左右相机的内外参——>对左右图像进行畸变校正——>选择匹配算法对校正后的图像进行匹配,计算视差。各匹配算法也遵循一定的流程,具体的细节在以后对匹配算法剖析中说明。
相机标定:
相机标定常用棋盘格标定法,网上提供的工具有很多,常用的是OpenCV或MATLAB提供的标定工具,具体网址如下:
http://wiki.ros.org/camera_calibration/Tutorials/MonocularCalibration
http://www.vision.caltech.edu/bouguetj/calib_doc/
相机标定后会有两个文件,分别对应内参矩阵和外参矩阵,OpenCV中两个文件为yml格式,其中内参文件intrinsics.yml中M1,M2为相机内参焦距(fx, fy),光心( cx, cy),D1,D2为相机畸变(k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]]),有4,5,8,12或14个元素。
左右图像畸变校正:
OpenCV中提供了图像校正的函数,操作如下:
stereoRectify( M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2 );
Mat map11, map12, map21, map22;
//输入的R1,P1可以来自StereoRectify,也可以直接来自标定后得到的矩阵
initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map11, map12);
initUndistortRectifyMap(M2, D2, R2, P2, img_size, CV_16SC2, map21, map22);
Mat img1r, img2r;
remap(img1, img1r, map11, map12, INTER_LINEAR);//img1须为灰度图
remap(img2, img2r, map21, map22, INTER_LINEAR);
有关stereoRectify和initUndistortRectifyMap的说明可以参考:
https://blog.csdn.net/u013341645/article/details/78710740
https://docs.opencv.org
图像匹配:
此处可以根据需要选择不同的匹配算法,OpenCV中匹配算法的调用方式是一样的,都是通过setParam和getParam来设置和获取算法参数值,然后通过compute执行算法,计算得到视差图,以下以BM为例展开:
//set bm's params
bm->setROI1(roi1);
bm->setROI2(roi2);
bm->setPreFilterCap(PrefilterSize);
bm->setPreFilterCap(PrefilterCap);
bm->setBlockSize(SADWindowSize > 0 ? SADWindowSize : 9);
bm->setMinDisparity(0);
bm->setNumDisparities(numberOfDisparities);
bm->setTextureThreshold(TextureThreshold);
bm->setUniquenessRatio(UniquenessRatio);
bm->setSpeckleWindowSize(SpeckleWindowSize);
bm->setSpeckleRange(SpeckleRange);
bm->setDisp12MaxDiff(Disp12MaxDiff);
bm->compute(img1, img2, disp);
disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));