SURF(Speeded Up Robust Features 加速的稳定的特征,不会随着环境变化而改变)特征关键特性:
-特征检测
-尺度空间 放缩到不同尺度空间,尺度不变性
-选择不变性 光照不变性,旋转不变性
-特征向量 将上面的特性描述成特征向量,然后就可以进行特征匹配
尺度不变性:人类在识别一个物体时,不管这个物体或远或近,都能对它进行正确的辨认,这就是所谓的尺度不变性。尺度空间理论经常与生物视觉关联,有人也称图像局部不变性特征为基于生物视觉的不变性方法。
旋转不变性:当这个物体发生旋转时,我们照样可以正确地辨认它,这就是所谓的旋转不变性。
SURF特征检测 工作原理
- 选择图像中POI( Points of Interest) 通过 Hessian Matrix 寻找
- 在不同的尺度空间发现关键点,非最大信号压制(通过3*3矩阵做卷积,如果覆盖的中心像素值是局部最大值,保留,否则丢弃)
- 发现特征点方法、旋转不变性要求 (旋转不变性 可忽略)
光照不变性:假设{12,24,48} {6,12,24} 两组数据,将它们归一化到 0-1 之间,得到的结果都是 {0,0.5,1} 这个就叫光照不变性(随着光的变化,各像素值呈同比例增减) 生成特征向量 有了上述不变性特征,就可以生成特征描述子
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);
}