基于ELSA的双目立体匹配算法

博主最近在研究双目测距的实现,要实现对高分辨率的图片进行实时匹配,对立体匹配算法的要求就比较苛刻。经过测试,OpenCV自带的BM、SGBM等算法对小图片的匹配效果还行,但是对高分辨率图片就力所不逮了。于是经过一番折腾,找到了这篇论文《Efficient Large-Scale Stereo Matching》及作者开源发布的源码库,但是发现源码库的example及网上相关资料均只能在VS的x86环境下运行,而受限于某些原因,我又只能在x64环境下运行,最后参考这位大佬的代码:链接,实现了ELAS算法在x64环境下的编译及运行。

代码运行环境:Win10+VS2015+OpenCV3.4.1

/*
	ElasMatch的形参必须为灰度图像,因为ELAS算法处理的图像格式为*.pgm,其为灰度图像对应的便携式图像格式。而黑白对应*.pbm格式、彩色对应着*.ppm格式。
*/
#include   
#include   
#include   
#include 
#include "elas.h"

using namespace std;
using namespace cv;

int ElasMatch(cv::Mat leftImage, cv::Mat rightImage);
int main() {

	Mat left = imread("L.jpg",IMREAD_GRAYSCALE);
	Mat right = imread("R.jpg",IMREAD_GRAYSCALE);
	
	ElasMatch(left, right);

	waitKey(0);
	return 0;
}
int ElasMatch(cv::Mat leftImage, cv::Mat rightImage)
{
	cv::Mat disp_l, disp_r, disp8u_l, disp8u_r;
	double minVal; double maxVal; 

	//cv::Mat leftImage = cv::imread("../test_images/leftr31.png", 0);
	//cv::Mat rightImage = cv::imread("../test_images/rightr31.png", 0);

	// generate disparity image using LIBELAS
	int bd = 0;
	const int32_t dims[3] = { leftImage.cols,leftImage.rows,leftImage.cols };
	cv::Mat leftdpf = cv::Mat::zeros(cv::Size(leftImage.cols, leftImage.rows), CV_32F);
	cv::Mat rightdpf = cv::Mat::zeros(cv::Size(leftImage.cols, leftImage.rows), CV_32F);
	Elas::parameters param;
	param.postprocess_only_left = false;
	Elas elas(param);
	elas.process(leftImage.data, rightImage.data, leftdpf.ptr<float>(0), rightdpf.ptr<float>(0), dims);

	cv::Mat(leftdpf(cv::Rect(bd, 0, leftImage.cols, leftImage.rows))).copyTo(disp_l);
	cv::Mat(rightdpf(cv::Rect(bd, 0, rightImage.cols, rightImage.rows))).copyTo(disp_r);

	//-- Check its extreme values
	cv::minMaxLoc(disp_l, &minVal, &maxVal);
	cout << "Min disp: Max value" << minVal << maxVal; //numberOfDisparities.= (maxVal - minVal)

	//-- Display it as a CV_8UC1 image
	disp_l.convertTo(disp8u_l, CV_8U, 255 / (maxVal - minVal));//(numberOfDisparities*16.)

	cv::minMaxLoc(disp_r, &minVal, &maxVal);
	cout << "Min disp: Max value" << minVal << maxVal; //numberOfDisparities.= (maxVal - minVal)

	//-- Display it as a CV_8UC1 image
	disp_r.convertTo(disp8u_r, CV_8U, 255 / (maxVal - minVal));//(numberOfDisparities*16.)

	cv::normalize(disp8u_l, disp8u_l, 0, 255, CV_MINMAX, CV_8UC1);    // obtain normalized image
	cv::normalize(disp8u_r, disp8u_r, 0, 255, CV_MINMAX, CV_8UC1);    // obtain normalized image

	cv::imshow("Left", leftImage);
	cv::imshow("Right", rightImage);

	cv::imshow("Elas_left", disp8u_l);
	cv::imshow("Elas_right", disp8u_r);
	cv::imwrite("Elas_left.png", disp8u_l);
	cv::imwrite("Elas_right.png", disp8u_r);

	cout << endl << "Over" << endl;
	//cv::waitKey(0);

	return 0;
}

论文原文+库文件+基于VS2015的工程实现等相关源代码见:ELAS算法原文+库文件+VS2015x64实现。

你可能感兴趣的:(三维重建,立体匹配,ELAS算法,C++)