SURF 特征匹配

      参考:http://www.cnblogs.com/ronny/p/4045979.html,博主对源码进行了分析,不过很多没看明白。

      分为几个部分。积分图:借助积分图像,图像与高斯二阶微分模板的滤波转化为对积分图像的加减运算。在哈尔特征中也用到这个。

                          DoH近似:将模板与图产像的卷积转换为盒子滤波运算,我们需要对高斯二阶微分模板进行简化,进而对Hessian矩阵行列式的值进行简化。使用近似的Hessian矩阵行列式的极大值检测斑点,

                    使用近似的Hessian矩阵行列式来表示图像中某一点x处的斑点响应值,遍历图像中所有的像元点, 便形成了在某一尺度下琉璃点检测的响应图像。

                  使用不同的模板尺寸,便形成了多尺度斑点响应的金字塔图像,利用这一金字塔图像,就可以进行斑点响应极值点的搜  索,其过程完全与SIFT算法类同。

                         尺度空间表示:通常想要获取不同尺度的斑点,必须建立图像的尺度空间金字塔。由于采用了盒子滤波和积分图像,并不需要像SIFT算法那样去直接建立图像金字塔,

                   而是采用不断增大盒子滤波模板的尺寸的间接方法。

                         兴趣点的定位:为了在图像及不同尺寸中定位兴趣点,我们用了3×3×3邻域非最大值抑制。 

 

 这篇博文说得很详细:http://www.cnblogs.com/wangguchangqing/p/4333873.html

 关于BFMatcher和FlannBasedMatcher,可参考:http://m.blog.csdn.net/blog/u012564690/40926315

#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"//因为在属性中已经配置了opencv等目录,所以把其当成了本地目录一样
#include <opencv2/nonfree/features2d.hpp>
#include "opencv2/highgui/highgui.hpp"
#include<opencv2/legacy/legacy.hpp>
/*这里用的是图像对图像集,注意FLANN的用法*/
using namespace cv;
using namespace std;

int main()
{
	Mat trainImage = imread("1.jpg"), trainImage_gray;
	cvtColor(trainImage, trainImage_gray, CV_BGR2GRAY);

	vector<KeyPoint> train_keypoint;
	Mat trainDescriptor;
	SurfFeatureDetector featureDector(80);//80是什么?
	featureDector.detect(trainImage_gray, train_keypoint);
	SurfDescriptorExtractor featureExtractor;

	featureExtractor.compute(trainImage_gray, train_keypoint, trainDescriptor);

	//创建基于FLANN的描述符匹配对象
	FlannBasedMatcher matcher;
	vector<Mat> train_desc_collection(1, trainDescriptor);//两个参数是什么
	matcher.add(train_desc_collection);//这两句什么意思
	matcher.train();

	VideoCapture cap("test.avi");
	unsigned int frameCount = 0;

	while (char(waitKey(1)) != 'q')
	{
		int64 time0 = getTickCount();
		Mat testImage, testIMage_gray;
		cap >> testImage;
		if (testImage.empty())
			continue;
		cvtColor(testImage, testIMage_gray, CV_BGR2GRAY);

		vector<KeyPoint> test_keyPoint;
		Mat testDescriptor;
		featureDector.detect(testIMage_gray, test_keyPoint);
		featureExtractor.compute(testIMage_gray, test_keyPoint, testDescriptor);

		vector<vector<DMatch>> matches;
		matcher.knnMatch(testDescriptor, matches, 2);//对每个匹配,返回两个最近邻匹配

		vector<DMatch> goodMatches;
		for (int i = 0; i < matches.size(); i++)
		{
			if (matches[i][0].distance < 0.6*matches[i][1].distance)//第一个匹配与第二个匹配距离
				                                                    //足够小时,才认为这是一个好的匹配
				goodMatches.push_back(matches[i][0]);
		}

		Mat dstImage;
		drawMatches(testImage, test_keyPoint, trainImage, train_keypoint, goodMatches, dstImage);
		imshow("匹配窗口", dstImage);
		
		cout << cvGetTickFrequency() / (getTickCount() - time0) << endl;
	}
	


	waitKey(0);
	return 0;
}

  

      

posted @ 2015-08-12 22:43  牧马人夏峥  阅读(1045)  评论(0编辑  收藏  举报