第六步,SGBM匹配
上一章部分对标定、校正的部分代码进行展示,本部分将对匹配这一块进行学习。
SGBM相关学习链接:
1,原始文献:Heiko Hirschmuller. Stereo processing by semiglobal matching and mutual information.Pattern Analysis and Machine Intelligence, IEEE Transactions on, 30(2):328–341, 2008.
2,cv::StereoSGBM Class Reference
SGBM的基本原理
SGBM的基本步骤涉及:预处理、代价计算、动态规划以及后处理
StereoSGBM的原型
static Ptr<StereoSGBM> cv::StereoSGBM::create
(
int minDisparity = 0,
int numDisparities = 16,
int blockSize = 3,
int P1 = 0,
int P2 = 0,
int disp12MaxDiff = 0,
int preFilterCap = 0,
int uniquenessRatio = 0,
int speckleWindowSize = 0,
int speckleRange = 0,
int mode = StereoSGBM::MODE_SGBM
)
第一个参数minDisparity,一般情况下为0,但有可能矫正算法会移动图像,因此,参数需要进行调整
第二个参数numDisparities,最大视差减最小视差,现在的算法中,参数必须为16所整除
第三个参数blockSize,块匹配的大小,应该为奇数,在3~11的范围
第四、五个参数P1,P2:控制视差图的光滑度
由于缺乏很多计算机及图像处理、计算机视觉的基础知识,比如路径规划、团块匹配等等
虽然很多细节没有搞懂,但通过连猜带蒙,把这部分程序搞的没有bug了
贴个其中一幅的视差图
SGBM部分程序
先放上SGBM的程序(原谅我很多不知道怎么处理,有些程序在瞎掰,比如传说中的cvLoadImage与Mat齐飞)
StereoSGBM sgbm;
int SADWindowSize = 9;
//预处理sobel,获得图像梯度信息,用于计算代价
sgbm.preFilterCap = 63;
//代价参数,得到SAD代价
int numberOfDisparities = 64;
sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3;
sgbm.minDisparity = 0;
sgbm.numberOfDisparities = numberOfDisparities;
//动态规划参数,默认四条路径
IplImage *img1= cvLoadImage("left01.jpg", 0);
int cn = img1->nChannels;
sgbm.P1 = 8 * cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
sgbm.P2 = 32 * cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
//后处理参数,唯一性检测、亚像素插值、左右一致性检测、连通区域检测
sgbm.uniquenessRatio = 10;
sgbm.speckleWindowSize = 100;
sgbm.speckleRange = 32;
sgbm.disp12MaxDiff = 1;
Mat disp, disp8;
for (i = 0; i < nframes; i++) {
cv::Mat img1 = cv::imread(imageNames[0][i].c_str(), 0);
cv::Mat img2 = cv::imread(imageNames[1][i].c_str(), 0);
cv::Mat img1r, img2r, disp, vdisp;
if (img1.empty() || img2.empty())
continue;
cv::remap(img1, img1r, map11, map12, cv::INTER_LINEAR);
cv::remap(img2, img2r, map21, map22, cv::INTER_LINEAR);
if (!isVerticalStereo || !useUncalibrated) {
// When the stereo camera is oriented vertically,
/