原文链接:OpenCV3.0立体匹配算法对比研究(SGBM、BM、GC)
原文博主已经写得很详细了,只是因为平台的原因,在代码实现上需要稍作修改
SCBM:Stereo Processing by Semi-global Matching and Mutual Information
详细的原理分析可以看这个链接:opencvSGBM半全局立体匹配算法的研究(1)
主要是改了三点:
1.//#include “stdafx.h”//20191104 我没有预编译头,去掉
2.#include <tchar.h>//20191104 添加这个库,不然 _TCHAR* argv[]会报错
3. cv::imwrite(“SGBM.jpg”, disp8U);//20191104 加上cv:: 不然无法保存
//#include "stdafx.h"//20191104 我没有预编译头,去掉
#include "opencv2/opencv.hpp"
#include <tchar.h>//20191104 添加这个库,不然 _TCHAR* argv[]会报错
using namespace std;
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
Mat left = imread("0_L.png", IMREAD_GRAYSCALE);
Mat right = imread("0_R.png", IMREAD_GRAYSCALE);
Mat disp;
int mindisparity = 0;
int ndisparities = 64;
int SADWindowSize = 11;
//SGBM
cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(mindisparity, ndisparities, SADWindowSize);
int P1 = 8 * left.channels() * SADWindowSize* SADWindowSize;
int P2 = 32 * left.channels() * SADWindowSize* SADWindowSize;
sgbm->setP1(P1);
sgbm->setP2(P2);
sgbm->setPreFilterCap(15);
sgbm->setUniquenessRatio(10);
sgbm->setSpeckleRange(2);
sgbm->setSpeckleWindowSize(100);
sgbm->setDisp12MaxDiff(1);
//sgbm->setMode(cv::StereoSGBM::MODE_HH);
sgbm->compute(left, right, disp);
disp.convertTo(disp, CV_32F, 1.0 / 16); //除以16得到真实视差值
Mat disp8U = Mat(disp.rows, disp.cols, CV_8UC1); //显示
normalize(disp, disp8U, 0, 255, NORM_MINMAX, CV_8UC1);
cv::imwrite("SGBM.jpg", disp8U);//20191104 加上cv:: 不然无法保存
return 0;
}
BM(bidirectional matching)算法:修改的地方同上
//#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include <tchar.h>
using namespace std;
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
Mat left = imread("0_L.png", IMREAD_GRAYSCALE);
Mat right = imread("0_R.png", IMREAD_GRAYSCALE);
Mat disp;
int mindisparity = 0;
int ndisparities = 64;
int SADWindowSize = 21;
cv::Ptr<cv::StereoBM> bm = cv::StereoBM::create(ndisparities, SADWindowSize);
// setter
bm->setBlockSize(SADWindowSize);
bm->setMinDisparity(mindisparity);
bm->setNumDisparities(ndisparities);
bm->setPreFilterSize(15);
bm->setPreFilterCap(31);
bm->setTextureThreshold(10);
bm->setUniquenessRatio(10);
bm->setDisp12MaxDiff(1);
copyMakeBorder(left, left, 0, 0, 80, 0, IPL_BORDER_REPLICATE); //防止黑边
copyMakeBorder(right, right, 0, 0, 80, 0, IPL_BORDER_REPLICATE);
bm->compute(left, right, disp);
disp.convertTo(disp, CV_32F, 1.0 / 16); //除以16得到真实视差值
disp = disp.colRange(80, disp.cols);
Mat disp8U = Mat(disp.rows, disp.cols, CV_8UC1);
normalize(disp, disp8U, 0, 255, NORM_MINMAX, CV_8UC1);
cv::imwrite("BM21.jpg", disp8U);
return 0;
}