Surf特征点检测与匹配

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\nonfree\features2d.hpp>
#include <opencv2\nonfree\nonfree.hpp>
#include <opencv2\calib3d\calib3d.hpp>
#include <iostream>

using namespace std;
using namespace cv;

vector<DMatch> ransac(vector<KeyPoint> queryKeyPoint,vector<KeyPoint> trainKeyPoint,vector<DMatch> matches);


int main(int argc,char* argv[])
{
	//定义图像
	Mat queryImage,trainImage;
	
	//读取图像
	queryImage = imread("3.jpg",IMREAD_COLOR);
	trainImage = imread("4.jpg",IMREAD_COLOR);
	//判断是否读取图像
	if(queryImage.empty() || trainImage.empty())
	{
		cerr<<"Failure in loading image"<<endl;
		return -1;
	}

	//定义Surf特征检测器
	SurfFeatureDetector surfDetector;

	//定义特征点
	vector<KeyPoint> queryKeyPoint,trainKeyPoint;

	//检测surf特征
	surfDetector.detect(queryImage,queryKeyPoint);
	surfDetector.detect(trainImage,trainKeyPoint);

	//查看检测到的特征点的数目
	cout<<"Number of queryKeyPoint:"<<queryKeyPoint.size()<<endl;
	cout<<"Number of trainKeyPoint:"<<trainKeyPoint.size()<<endl;

	//定义绘制surf特征点的图像
	Mat queryImageKeyPoint,trainImageKeyPoint;

	//绘制surf特征点
	drawKeypoints(queryImage,queryKeyPoint,queryImageKeyPoint,Scalar(0,0,255),
		/*DrawMatchesFlags::DRAW_RICH_KEYPOINTS*/DrawMatchesFlags::DEFAULT);
	drawKeypoints(trainImage,trainKeyPoint,trainImageKeyPoint,Scalar(0,0,255),
		/*DrawMatchesFlags::DRAW_RICH_KEYPOINTS*/DrawMatchesFlags::DEFAULT);

	//定义显示窗口,可不要
	namedWindow("queryImageKeyPoint",CV_WINDOW_AUTOSIZE);
	namedWindow("trainImageKeyPoint",CV_WINDOW_AUTOSIZE);

	//显示surf特征点
	imshow("queryImageKeyPoint",queryImageKeyPoint);
	imshow("trainImageKeyPoint",trainImageKeyPoint);

	//定义surf特征描述子
	Mat queryDescriptor,trainDescriptor;

	//定义Surf特征描述子提取器
	SurfDescriptorExtractor surfExtractor;

	//提取特征描述子
	surfExtractor.compute(queryImage,queryKeyPoint,queryDescriptor);
	surfExtractor.compute(trainImage,trainKeyPoint,trainDescriptor);
	
	//定义描述子匹配对
	vector<DMatch> bfMatches;
	vector<DMatch> flannMatches;

	//Brute Match,穷举法求最近邻
	BFMatcher bfMatcher;
	bfMatcher.match(queryDescriptor,trainDescriptor,bfMatches);

	//FlannBasedMatcher,最近邻近似匹配
	FlannBasedMatcher flannMatcher;
	flannMatcher.match(queryDescriptor,trainDescriptor,flannMatches);


	//对匹配点进行RANSAC过滤
	vector<DMatch> ransac_BFMatches,ransac_FlannMatches;

	ransac_BFMatches=ransac(queryKeyPoint,trainKeyPoint,bfMatches);
	ransac_FlannMatches=ransac(queryKeyPoint,trainKeyPoint,flannMatches);

	//定义匹配图像
	Mat bfMatchImage,flannMatchImage;

	//绘制匹配图像
	//drawMatches(queryImage,queryKeyPoint,trainImage,trainKeyPoint,bfMatches,bfMatchImage);
	//drawMatches(queryImage,queryKeyPoint,trainImage,trainKeyPoint,flannMatches,flannMatchImage);
	drawMatches(queryImage,queryKeyPoint,trainImage,trainKeyPoint,ransac_BFMatches,bfMatchImage);
	drawMatches(queryImage,queryKeyPoint,trainImage,trainKeyPoint,ransac_FlannMatches,flannMatchImage);
	
	//显示匹配结果
	imshow("BFMatch",bfMatchImage);
	imshow("FlannMatch",flannMatchImage);


	waitKey(0);
	return 0;
}

vector<DMatch> ransac(vector<KeyPoint> queryKeyPoint,vector<KeyPoint> trainKeyPoint,vector<DMatch> matches)
{
	cout<<"ransac前:"<<matches.size()<<endl;
	vector<Point2f> queryPoints(matches.size()),trainPoints(matches.size());
	for(int i=0;i<matches.size();i++)
	{
		queryPoints[i] = queryKeyPoint[matches[i].queryIdx].pt; 
		trainPoints[i] = trainKeyPoint[matches[i].trainIdx].pt; 
	}

	Mat H;
	vector<unsigned char> inlierMask(matches.size());
	vector<DMatch> ransac_matches;
	H = findHomography(queryPoints,trainPoints,CV_RANSAC,3,inlierMask);

	for(int i=0;i<inlierMask.size();i++)
	{
		if(inlierMask[i])
		{
			ransac_matches.push_back(matches[i]);
		}
	}
	cout<<"ransac后:"<<ransac_matches.size()<<endl;
	return ransac_matches;
}

SURF原理:http://blog.csdn.net/quincuntial/article/details/50461274


匹配结果:


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值