使用OpenCV3进行SURF特征提取和暴力匹配代码详解

    首先声明,程序代码来自于http://blog.csdn.net/taily_duan/article/details/53112896,这里使用MiddleBury的图片集进行了测试,并且对代码做一个详细的解释。

    之前使用OpenCV2.4.9,升级到3.2.0以后发现SURF特征提取的使用发生较大的变化,配置好新版本的opencv稳定模块和contrib模块后,原来的代码还是提示未声明的标识符,发现是新版本SURF使用方法调整了,所以借鉴新的SURF特征提取代码。


#include   
#include   
#include "opencv2/core.hpp"  
#include "opencv2/core/utility.hpp"  
#include "opencv2/core/ocl.hpp"  
#include "opencv2/imgcodecs.hpp"  
#include "opencv2/highgui.hpp"  
#include "opencv2/features2d.hpp"  
#include "opencv2/calib3d.hpp"  
#include "opencv2/imgproc.hpp"  
#include"opencv2/flann.hpp"  
#include"opencv2/xfeatures2d.hpp"  
#include"opencv2/ml.hpp"  

using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
using namespace cv::ml;

int main()
{
	Mat a = imread("3.png", 0);//左右相机的图像来源于MiddleBury图片库  
	Mat b = imread("4.png", 0);

	Ptr surf;            //创建方式和OpenCV2中的不一样,并且要加上命名空间xfreatures2d
                                   //否则即使配置好了还是显示SURF为未声明的标识符  
	surf = SURF::create(800);

	BFMatcher matcher;         //实例化一个暴力匹配器
	Mat c, d;          
	vectorkey1, key2;
	vector matches;    //DMatch是用来描述匹配好的一对特征点的类,包含这两个点之间的相关信息
	                           //比如左图有个特征m,它和右图的特征点n最匹配,这个DMatch就记录它俩最匹配,并且还记录m和n的
	                           //特征向量的距离和其他信息,这个距离在后面用来做筛选

	surf->detectAndCompute(a, Mat(), key1, c);//输入图像,输入掩码,输入特征点,输出Mat,存放所有特征点的描述向量
	surf->detectAndCompute(b, Mat(), key2, d);//这个Mat行数为特征点的个数,列数为每个特征向量的尺寸,SURF是64(维)

	matcher.match(c, d, matches);             //匹配,数据来源是特征向量,结果存放在DMatch类型里面  
	
	                                          //sort函数对数据进行升序排列
	sort(matches.begin(), matches.end());     //筛选匹配点,根据match里面特征对的距离从小到大排序
	vector< DMatch > good_matches;
	int ptsPairs = std::min(50, (int)(matches.size() * 0.15));
	cout << ptsPairs << endl;
	for (int i = 0; i < ptsPairs; i++)
	{
		good_matches.push_back(matches[i]);//距离最小的50个压入新的DMatch
	}
	Mat outimg;                                //drawMatches这个函数直接画出摆在一起的图
	drawMatches(a, key1, b, key2, good_matches, outimg, Scalar::all(-1), Scalar::all(-1), vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);  //绘制匹配点  


	imshow("桌面", outimg);
	cvWaitKey(0);
}


你可能感兴趣的:(双目视觉)