特征点检测之surf算法

来源:互联网 发布:h5游戏模板源码 编辑:程序博客网 时间:2024/05/22 14:57

四、尺度不变的SURF特征检测

        当我们想匹配不同图像时,经常会遇到图像尺度不同的问题,不同图像中特征点的距离变得不同,物体变成不同的尺寸,如果我们通过修正特征点的大小,就会造成强度不匹配。为了解决这个问题,我们提出一个尺度不变的SURF特征检测,在计算特征点的时候把尺度因素加入之中。SURF与SIFT算法相似,SIFT算法比较稳定,检测特征点更多,但是复杂度较高,而SURF要运算简单,效率高,运算时间短一点。

       4.1 SURF算法简介

       为了实现尺度不变性的特征点检测与匹配,SURF算法与SIFT算法的第一步都是构造图像多尺度空间(图像金字塔)。sift算法使用高斯卷积,高斯函数有两个参数,高斯核的尺寸K与σ值,默认最底层(0层)的σ = 1.6,原图像的σ=0.5(σ越大图像越模糊,所以源图像是最清晰的),尺寸空间即图像金字塔,Ksize决定有个塔,σ决定每个塔有几层(Octave),不同K和σ构造出的尺寸空间。在这种多尺度空间计算特征点就满足了尺度不变的特性。但是sift使用高斯卷积计算复杂,SURF算法则用高斯滤波与Hessian矩阵结合近似实现多尺度空间,计算复杂度降低多了。


同一层中k的值改变,不同层是σ的值改变

       SURF第二步是根据非极大值抑制初步确定特征点,与SIFT相似。

       第三步根据3维线性插值法得到半像素点的特征点,最后选取特征点的主方向,SURF是对特征点进行邻域统计,取半径为6S(单位)的圆区域,统计那个60°的扇形中haar小波特征总和最大,即为最大特征点主方向。

       第四步构造特征点算术描述子,SURF算法是选取一个20S(单位)的区域,分成4X4分,每一份中有5X5S,统计一份中的∑dx,∑dy,∑|dx|,∑|dy|,这样就得到4X4X4 = 64的向量描述子。SIFT是128个描述子,比SURF复杂一点。

       

       4.2 opencv实现

       4.2.1 SURF的函数接口

       程序实例:       

// Read input imageimage= cv::imread("church03.jpg",0);keypoints.clear();// Construct the SURF feature detector objectcv::SurfFeatureDetector surf(2500);// Detect the SURF featuressurf.detect(image,keypoints);cv::Mat featureImage;cv::drawKeypoints(image,keypoints,featureImage,cv::Scalar(255,255,255),cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);    // Display the cornerscv::namedWindow("SURF Features");cv::imshow("SURF Features",featureImage);cv::imwrite("SURF Features.jpg",featureImage);
       程序结果:

       

     4.2.2 SIFT函数接口

     程序如下: 

// Read input imageimage= cv::imread("church01.jpg",0);keypoints.clear();// Construct the SURF feature detector objectcv::SiftFeatureDetector sift(0.03,  // feature threshold10.);  // threshold to reduce           // sensitivity to lines// Detect the SURF featuressift.detect(image,keypoints);cv::drawKeypoints(image,keypoints,featureImage,cv::Scalar(255,255,255),cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);    // Display the cornerscv::namedWindow("SIFT Features");cv::imshow("SIFT Features",featureImage);cv::imwrite("SIFT Features.jpg",featureImage);
    程序结果如下

    

 五、 SURF特征点描述

         如上面例子可以看出,SURF算法为每一个特征点都定义了一个位置和大小,这个大小因素可以用于定义一个特征点附近的相同视觉不同尺寸大小的窗口,用来识别特征点区别于其他特征点。根据特征描述符即SURF中64个向量,比较两幅图形中不同特征点的向量的欧拉距离,选取距离最小的前25个点,就是所寻找的最佳匹配点。

        5.1 SURF匹配算法opencv实现

       

#include <iostream>#include <vector>#include <opencv2/core/core.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/nonfree/features2d.hpp>#include <opencv2/legacy/legacy.hpp>using namespace  std;using namespace  cv;int main(){// Read input imagescv::Mat image1= cv::imread("church01.jpg",0);cv::Mat image2= cv::imread("church02.jpg",0);if (!image1.data || !image2.data)return 0;     // Display the imagescv::namedWindow("Right Image");cv::imshow("Right Image",image1);cv::namedWindow("Left Image");cv::imshow("Left Image",image2);// vector of keypointsstd::vector<cv::KeyPoint> keypoints1;std::vector<cv::KeyPoint> keypoints2;// Construction of the SURF feature detector cv::SurfFeatureDetector surf(3000);// Detection of the SURF featuressurf.detect(image1,keypoints1);surf.detect(image2,keypoints2);std::cout << "Number of SURF points (1): " << keypoints1.size() << std::endl;std::cout << "Number of SURF points (2): " << keypoints2.size() << std::endl;// Draw the kepointscv::Mat imageKP;cv::drawKeypoints(image1,keypoints1,imageKP,cv::Scalar(255,255,255),cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);cv::namedWindow("Right SURF Features");cv::imshow("Right SURF Features",imageKP);cv::drawKeypoints(image2,keypoints2,imageKP,cv::Scalar(255,255,255),cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);cv::namedWindow("Left SURF Features");cv::imshow("Left SURF Features",imageKP);// Construction of the SURF descriptor extractor cv::SurfDescriptorExtractor surfDesc;// Extraction of the SURF descriptorscv::Mat descriptors1, descriptors2;surfDesc.compute(image1,keypoints1,descriptors1);surfDesc.compute(image2,keypoints2,descriptors2);std::cout << "descriptor matrix size: " << descriptors1.rows << " by " << descriptors1.cols << std::endl;// Construction of the matcher cv::BruteForceMatcher<cv::L2<float>> matcher;// Match the two image descriptorsstd::vector<cv::DMatch> matches;matcher.match(descriptors1,descriptors2, matches);std::cout << "Number of matched points: " << matches.size() << std::endl;std::nth_element(matches.begin(),    // initial position             matches.begin()+24, // position of the sorted element matches.end());     // end position// remove all elements after the 25thmatches.erase(matches.begin()+25, matches.end()); cv::Mat imageMatches;cv::drawMatches(image1,keypoints1,  // 1st image and its keypoints            image2,keypoints2,  // 2nd image and its keypointsmatches,// the matchesimageMatches,// the image producedcv::Scalar(255,255,255)); // color of the linescv::namedWindow("Matches");cv::imshow("Matches",imageMatches);cv::imwrite("Matches.jpg",imageMatches);cv::waitKey();return 0;}
     程序结果显示:


参考资料:

    SIFT 特征提取算法总结  http://www.cnblogs.com/cfantaisie/archive/2011/06/14/2080917.html

特征点检测学习_2(surf算法) http://www.cnblogs.com/tornadomeet/archive/2012/08/17/2644903.html

原创粉丝点击