关于双目测距中立体匹配算法的研究[一]
1.概述
目前常用的立体匹配算法有BM(blocking match块匹配),SGBM(semi-global BM),GC(graph cut图割);传统的立体匹配算法中,全局匹配算法都无法满足实时性的要求,因此此处只对BM和SGBM这种局部匹配法进行分析和优化,GC是全局匹配不做介绍。
2.BM算法
2.1 BM算法的原理
BM算法是一种基于SAD窗的局部匹配算法,思想是以左目图像的源匹配点为中心,定义一个窗口D,其大小为(2m+1X2n+1),统计其窗口的灰度值的和,然后在右目图像中逐步计算其左右窗口的灰度和的差值,最后搜索到的差值最小的区域的中心像素即为匹配点。基于SAD窗口的BM算法的处理速度很快,理论上一副320X240的灰度图匹配时间为30ms。实验使用640X480的镜头,测算出平均耗时约为90ms。但是这种算法只能用于处理简单场景,对于稍微复杂的场景会存在边缘匹配关键点缺失的信息丢失问题,严重影响测距性能。
2.2 BM算法的代码实现
2.2.1 BM算法在OpenCV中的源码分析
#include <opencv2/opencv.hpp>
#include <windows.h>
#include <iostream>
using namespace std;
using namespace cv;
Mat ImageL, ImageR;
Ptr<StereoBM> bm = StereoBM::create(32, 15);
int main()
{
long start = GetTickCount();
ImageL = imread("ll.jpg",0);
ImageR = imread("rr.jpg",0);
bm->setBlockSize(15);
bm->setPreFilterCap(31);
bm->setMinDisparity(0);
bm->setNumDisparities(32);
bm->setTextureThreshold(10);
bm->setUniquenessRatio(10);
bm->setSpeckleWindowSize(100);
bm->setSpeckleRange(32);
bm->setDisp12MaxDiff(-1);
Mat disp, disp8;
bm->compute(ImageL, ImageR, disp);
disp.convertTo(disp8, CV_8U, 255 / ((32)*16.));
long stop = GetTickCount();
cout << (stop - start) << "ms" << endl;
imshow("disparity", disp8);
waitKey(0)