最近一直在学习SGBM算法,作为一种全局匹配算法,立体匹配的效果明显好于局部匹配算法,但是同时复杂度上也要远远大于局部匹配算法。算法主要是参考Stereo Processing by Semiglobal Matching and Mutual Information,里面有讲完整的算法实现。
OpenCV中实际上是提供了SGBM类进行SGBM算法的实现。
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
IplImage * img1 = cvLoadImage("left.png",0);
IplImage * img2 = cvLoadImage("right.png",0);
cv::StereoSGBM sgbm;
int SADWindowSize = 9;
sgbm.preFilterCap = 63;
sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3;
int cn = img1->nChannels;
int numberOfDisparities=64;
sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
sgbm.minDisparity = 0;
sgbm.numberOfDisparities = numberOfDisparities;
sgbm.uniquenessRatio = 10;
sgbm.speckleWindowSize = 100;
sgbm.speckleRange = 32;
sgbm.disp12MaxDiff = 1;
Mat disp, disp8;
int64 t = getTickCount();
sgbm((Mat)img1, (Mat)img2, disp);
t = getTickCount() – t;
cout<
disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));
namedWindow("left", 1);
cvShowImage("left", img1);
namedWindow("right", 1);
cvShowImage("right", img2);
namedWindow("disparity", 1);
imshow("disparity", disp8);
waitKey();
imwrite("sgbm_disparity.png", disp8);
cvDestroyAllWindows();
return 0;
}
贴出效果:
//深度图
但是仅仅用OpenCV自带的SGBM类来实现并不能满足,我还是希望能够自己实现该算法,然后最关键是移植到FPGA上去。
于是我尝试自已去写SGBM的代码,论文中提高Dynamic programming算法,实际上SGBM中也用到了多方向的Dynamic programming,但是我目前只是实现了单方向的DP。
//引入概率公式
//引入CBT的插值方法
//加上相邻匹配点位置之间的限制
#include
#include
#include
#include
#include
#include
using namespace std;
const int Width = 1024;
const int Height = 1024;
int Ddynamic[Width][Width];
//使用钟形曲线作为匹配概率,差值越小则匹配的概率越大,最终的要求是使匹配的概率最大,概率曲线使用matlab生成
//均方差30
//int Probability[256] = {
//