• 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;
    }
    

      

          

  • 相关阅读:
    【XFeng安卓开发笔记】Android开发中如何调用打电话功能
    【XFeng安卓开发笔记】edittext中怎样禁止系统自带键盘弹出但光标还在
    【XFeng安卓开发笔记】android 如何在对话框中获取edittext中的数据
    【nRF51822蓝牙开发笔记】点亮LED灯
    基于R7F0C80212ESP的蓝牙婴儿早教机
    read、write和lseek
    open(/dev/ietctl, O_RDWR) 函数
    通过linux命令来控制板上GP_LED灯亮灭
    更新开发板固件
    PHP_EOL
  • 原文地址:https://www.cnblogs.com/573177885qq/p/4725798.html
Copyright © 2020-2023  润新知