以OpenCV自带的Aloe图像对为例:
1.BM算法(Block Matching)
参数设置如下:
int numberOfDisparities = ((imgSize.width / 8) + 15) & -16; cv::Ptr<cv::StereoBM> bm = cv::StereoBM::create(16, 9); cv::Rect roi1, roi2; bm->setROI1(roi1); bm->setROI2(roi2); bm->setPreFilterCap(31); bm->setBlockSize(9); bm->setMinDisparity(0); bm->setNumDisparities(numberOfDisparities); bm->setTextureThreshold(10); bm->setUniquenessRatio(15); bm->setSpeckleWindowSize(100); bm->setSpeckleRange(32); bm->setDisp12MaxDiff(1); bm->compute(imgL, imgR, disp);
效果如下:
BM算法得到的视差图(左),空洞填充后得到的视差图(右)
2.SGBM(Semi-Global Block matching)算法:
参数设置如下:
enum { STEREO_BM = 0, STEREO_SGBM = 1, STEREO_HH = 2, STEREO_VAR = 3, STEREO_3WAY = 4 }; int numberOfDisparities = ((imgSize.width / 8) + 15) & -16; cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(0, 16, 3); sgbm->setPreFilterCap(63); int SADWindowSize = 9; int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3; sgbm->setBlockSize(sgbmWinSize); int cn = imgL.channels(); sgbm->setP1(8 * cn*sgbmWinSize*sgbmWinSize); sgbm->setP2(32 * cn*sgbmWinSize*sgbmWinSize); sgbm->setMinDisparity(0); sgbm->setNumDisparities(numberOfDisparities); sgbm->setUniquenessRatio(10); sgbm->setSpeckleWindowSize(100); sgbm->setSpeckleRange(32); sgbm->setDisp12MaxDiff(1); int alg = STEREO_SGBM; if (alg == STEREO_HH) sgbm->setMode(cv::StereoSGBM::MODE_HH); else if (alg == STEREO_SGBM) sgbm->setMode(cv::StereoSGBM::MODE_SGBM); else if (alg == STEREO_3WAY) sgbm->setMode(cv::StereoSGBM::MODE_SGBM_3WAY); sgbm->compute(imgL, imgR, disp);
效果如图:
SGBM算法得到的视差图(左),空洞填充后得到的视差图(右)
可见SGBM算法得到的视差图相比于BM算法来说,减少了很多不准确的匹配点,尤其是在深度不连续区域,速度上SGBM要慢于BM算法。OpenCV3.0以后没有实现GC算法,可能是出于速度考虑,以后找时间补上对比图,以及各个算法的详细原理分析。
后面我填充空洞的效果不是很好,如果有更好的方法,望不吝赐教。