SURF特征检测
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},这个就叫光照不变 性(随着光的变化,各像素值呈同比例增减)
- 生成特征向量 有了上述不变性特征,就可以生成特征描述子
一般来说,标准的SURF算子比SIFT算子快好几倍,并且在多幅图片下具有更好的稳定性。SURF最大的特征在于采用了harr特征以及积分图像的概念,这大大加快了程序的运行时间。SURF可以应用于计算机视觉的物体识别以及3D重构中。
API:
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 <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include<iostream>
#include<math.h>
#include <string>
#include<fstream>
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
Mat src, graysrc;
int minHesssian = 100;
int maxhessian = 500;
void Surf(int, void*) {
Ptr<SURF> detector = SURF::create(minHesssian);// SURF特征检测类,Ptr 智能指针
vector<KeyPoint>keypoint;//特征点
detector->detect(src,keypoint);//特征检测
cout << "keypoint_size=" << keypoint.size() << endl;
Mat dst;
drawKeypoints(src, keypoint, dst, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
imshow("output", dst);
}
int main() {
src = imread("C:/Users/Administrator/Desktop/pic/1-H.jpg");
imshow("input", src);
//cvtColor(src, graysrc, CV_BGR2GRAY);
Surf(0, 0);
createTrackbar("yuzhi", "output", &minHesssian, maxhessian, Surf);
waitKey(0);
}
结果:
SIFT特征检测(斑点检测)
SIFT(Scale-Invariant Feature Transform 尺度不变性特征变换)特征检测关键特性:
- -建立尺度空间,寻找极值(最小最大值)
- -关键点定位(寻找关键点准确位置与删除弱边缘)
- -关键点方向指定
- -关键点描述子
计算图像 x y 方向梯度获取像素位置的梯度,并以梯度计算直方图,最后统计出bins最高的梯度,这个梯度就是关键点的方向。
算法特点:
- 特征是图像的局部特征,其对旋转,尺度缩放,亮度变化保持不变形,对视角变化,仿射变换,噪声也保持一定的稳定性。
- 独立性好,信息丰富使用与海量特征数据库中进行快速准确的匹配。
- 多量性,即使少数的几个物体也可以产生大量的SIFT特征向量。
- 高速
解决的问题:
- 目标的旋转,缩放平移
- 图像仿射/投影变换
- 光照影响
- 目标遮挡
- 杂物场景
- 噪声
SIFT算法的实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。
SIFT在图像的不变特征提取方面拥有无与伦比的优势,但并不完美,仍然存在:
1. 实时性不高。
2. 有时特征点较少。
3. 对边缘光滑的目标无法准确提取特征点。
API:
static Ptr<cv::xfeatures2d::SIFT> cv::xfeatures2d::SIFT::create( // SIFT特征检测
int nfeatures = 0, // number of features 想求的特征的数量,越多计算量越大
int nOctaveLayers = 3, // 高斯金字塔的层级数,最小3,小于3就没有SIFT的尺度不变性的特点了