OpenCV之图像特征提取与检测(八) SURF特征检测

SURF(Speeded Up Robust Features 加速的稳定的特征,不会随着环境变化而改变)特征关键特性:

-特征检测
-尺度空间   放缩到不同尺度空间,尺度不变性
-选择不变性      光照不变性,旋转不变性
-特征向量   将上面的特性描述成特征向量,然后就可以进行特征匹配
  • 尺度不变性:人类在识别一个物体时,不管这个物体或远或近,都能对它进行正确的辨认,这就是所谓的尺度不变性。尺度空间理论经常与生物视觉关联,有人也称图像局部不变性特征为基于生物视觉的不变性方法。

  • 旋转不变性:当这个物体发生旋转时,我们照样可以正确地辨认它,这就是所谓的旋转不变性。

SURF特征检测 工作原理

  1. 选择图像中POI( Points of Interest) 通过 Hessian Matrix 寻找
    这里写图片描述
    这里写图片描述
  2. 在不同的尺度空间发现关键点,非最大信号压制(通过3*3矩阵做卷积,如果覆盖的中心像素值是局部最大值,保留,否则丢弃)
    这里写图片描述
  3. 发现特征点方法、旋转不变性要求 (旋转不变性 可忽略)
    光照不变性:假设{12,24,48} {6,12,24} 两组数据,将它们归一化到 0-1 之间,得到的结果都是 {0,0.5,1} 这个就叫光照不变性(随着光的变化,各像素值呈同比例增减)
  4. 生成特征向量 有了上述不变性特征,就可以生成特征描述子
    这里写图片描述

    static Ptr<cv::xfeatures2d::SURF> cv::xfeatures2d::SURF::create(
        double hessianThreshold=100, // -HessianThreshold 最小的Hessian阈值  值可选300~500之间
        int nOctaves = 4, // -Octaves – 4表示在四个尺度空间
        int nOctaveLayers = 3, // OctaveLayers – 表示每个尺度的层数
        bool extended = false, 
        bool upright = false // -upright 0- 表示计算选择不变性, 1表示不计算,速度更快
    );
    

代码

    #include "../common/common.hpp"

    using namespace cv::xfeatures2d;

    static Mat src;
    static const char title[] = "SURF KeyPoints";
    static int minHessian = 100; // 最小的Hessian阈值
    static int max_count = 500;

    static void surf_detect(int, void*);

    void main(int argc, char** argv)
    {
        src = imread(getCVImagesPath("images/test1_3.png"), IMREAD_GRAYSCALE);
        imshow("src2-9", src);

        namedWindow(title, CV_WINDOW_AUTOSIZE);
        createTrackbar("minHessian:", title, &minHessian, max_count, surf_detect);
        surf_detect(0, 0);

        waitKey(0);
    }

    void surf_detect(int, void*)
    {
        if (minHessian < 100) minHessian = 100;
        // SURF特征检测
        Ptr<SURF> detector = SURF::create(minHessian); // SURF特征检测类,Ptr 智能指针
        vector<KeyPoint> keypoints; // SURF特征点
        detector->detect(src, keypoints, Mat()); // SURF特征检测
        cout << "keypoints.size=" << keypoints.size() << endl;

        Mat keypoint_img;
        drawKeypoints(src, keypoints, keypoint_img, Scalar::all(-1), DrawMatchesFlags::DEFAULT); // 绘制关键点
        imshow(title, keypoint_img);
    }

效果图

这里写图片描述

猜你喜欢

转载自blog.csdn.net/huanghuangjin/article/details/81269486