具体的算法原理请移步opencvSGBM半全局立体匹配算法的研究(1)
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main() {
//读图
Mat left_img = imread("D:\\学习资料\\C++\\C++ code\\semiglobalmatching-master\\Data\\Teddy\\im2.png", 0);
Mat right_img = imread("D:\\学习资料\\C++\\C++ code\\semiglobalmatching-master\\Data\\Teddy\\im6.png", 0);
//创建SGBM对象
int mindisparity = 0;
int ndisparities = 64;
int SADWindowSize = 9;
Ptr<StereoSGBM> sgbm = StereoSGBM::create(mindisparity, ndisparities, SADWindowSize);
//设置SGBM参数
int P1 = 8 * left_img.channels() * SADWindowSize * SADWindowSize;
int P2 = 32 * left_img.channels() * SADWindowSize * SADWindowSize;
sgbm->setP1(P1);
sgbm->setP2(P2);
sgbm->setPreFilterCap(15);
sgbm->setUniquenessRatio(10);
sgbm->setSpeckleRange(2);
sgbm->setSpeckleWindowSize(50);
sgbm->setDisp12MaxDiff(1);
sgbm->setMode(cv::StereoSGBM::MODE_HH);
//计算视差
Mat disp;
sgbm->compute(left_img, right_img, disp);
disp.convertTo(disp, CV_32F, 1.0 / 16); //除以16得到真实视差图
//视差图显示
Mat disp8U = Mat(disp.rows, disp.cols, CV_8UC1);
disp.convertTo(disp8U, CV_8UC1, 255. / ndisparities);
//normalize(disp, disp8U, 0, 255, NORM_MINMAX, CV_8UC1); //这种归一化的方法是错误的,误匹配率为99%
imshow("disparity", disp8U);
waitKey(0);
imwrite("output_disparity.png", disp8U);
system("pause");
return 0;
}
上面是sgbm的代码,然后我们来看一下结果视差图的显示:
然后看一下Ground truth:
有了真实的视差图和计算视差图之后,我们自然要看看sgbm算法的误匹配率是多少。
#include
#include
#include
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
cv::Mat GT;
cv::Mat output_disparity;
Mat occl, occ_and_discont, occ_and_textl;
GT = cv::imread("D:\\学习资料\\C++\\C++ code\\semiglobalmatching-master\\Data\\Teddy\\disp2.png", CV_LOAD_IMAGE_GRAYSCALE);
output_disparity = cv::imread("D:\\学习资料\\C++\\C++ code\\SGBM\\SGBM\\output_disparity.png", CV_LOAD_IMAGE_GRAYSCALE);
occl = imread("D:\\学习资料\\C++\\C++ code\\middleburry_dataset\\occl.png", CV_LOAD_IMAGE_GRAYSCALE);
occ_and_discont = imread("D:\\学习资料\\C++\\C++ code\\middleburry_dataset\\occ_and_discont.png", CV_LOAD_IMAGE_GRAYSCALE);
occ_and_textl = imread("D:\\学习资料\\C++\\C++ code\\middleburry_dataset\\occ_and_textl.png", CV_LOAD_IMAGE_GRAYSCALE);
if (!GT.data || !output_disparity.data || !occl.data || !occ_and_discont.data || !occ_and_textl.data) {
std::cerr << "Could not open or find one of the images!" << std::endl;
return -1;
}
if (GT.rows != output_disparity.rows || GT.cols != output_disparity.cols || GT.rows != occl.rows || GT.cols != occl.cols
|| GT.rows != occ_and_discont.rows || GT.cols != occ_and_discont.cols || GT.rows != occ_and_textl.rows
|| GT.cols != occ_and_textl.cols) {
std::cerr << "Error: The images have different dimensions!" << std::endl;
return -2;
}
unsigned long all, nonoccl, discont, textl;
unsigned long all_counter, nonoccl_counter, discont_counter, textl_counter;
all = nonoccl = discont = textl = all_counter = nonoccl_counter = discont_counter = textl_counter = 0;
for (int row = 0; row < GT.rows; ++row) {
for (int col = 0; col < GT.cols; ++col) {
//统计总体的误匹配率
if (GT.at<uchar>(row, col) != 0) {
all_counter++;
if (abs(GT.at<uchar>(row, col) - output_disparity.at<uchar>(row, col)) > 4) {
all++;
}
}
//统计非遮挡的误匹配率
if (occl.at<uchar>(row, col) != 0) {
nonoccl_counter++;
if (abs(GT.at<uchar>(row, col) - output_disparity.at<uchar>(row, col)) > 4) {
nonoccl++;
}
}
//统计深度不连续的误匹配率
if (occ_and_discont.at<uchar>(row, col) == 255) {
discont_counter++;
if (abs(GT.at<uchar>(row, col) - output_disparity.at<uchar>(row, col)) > 4) {
discont++;
}
}
//统计无纹理的误匹配率
if (occ_and_textl.at<uchar>(row, col) == 255) {
textl_counter++;
if (abs(GT.at<uchar>(row, col) - output_disparity.at<uchar>(row, col)) > 4) {
textl;
}
}
}
}
cout << "rows * cols = " << GT.rows * GT.cols << endl;
cout << "all_counter = " << all_counter << endl;
cout << "all = " << all << endl;
cout << "ALL errer: ";
std::cout << 100 * double(all / double(all_counter)) << "%" << endl;
cout << endl;
cout << "nonoccl_counter = " << nonoccl_counter << endl;
cout << "nonoccl = " << nonoccl << endl;
cout << "nonoccl errer: ";
std::cout << 100 * double(nonoccl / double(nonoccl_counter)) << "%" << endl;
cout << endl;
cout << "discont_counter = " << discont_counter << endl;
cout << "discont = " << discont << endl;
cout << "discont errer: ";
std::cout << 100 * double(discont / double(discont_counter)) << "%" << endl;
cout << endl;
cout << "textl_counter = " << textl_counter << endl;
cout << "textl = " << textl << endl;
cout << "textl errer: ";
std::cout << 100 * double(textl / double(textl_counter)) << "%" << endl;
system("pause");
return 0;
}
rows * cols = 168750
all_counter = 165344
all = 46198
ALL errer: 27.9405%
nonoccl_counter = 147651
nonoccl = 29056
nonoccl errer: 19.6788%
discont_counter = 40517
discont = 14778
discont errer: 36.4736%
textl_counter = 18081
textl = 0
textl errer: 0%
总体的误匹配率是28%,可以看到误匹配率还是挺高的。经过参数调整之后,该数值变化不大。