SIFT特征检测介绍 SIFT(Scale-Invariant Feature Transform)特征检测关键特性:
-建立尺度空间,寻找极值
-关键点定位(寻找关键点准确位置与删除弱边缘)
-关键点方向指定
-关键点描述子
关键点定位
我们在像素级别获得了极值点的位置,但是更准确的 值应该在亚像素位置,如何得到 – 这个过程称为关键 点(准确/精准)定位
删除弱边缘- 通过Hassian 矩阵特征值实现,小于阈值 自动舍
建立尺度空间,寻找极值。工作原理
1. 构建图像高斯金字塔,求取DOG,发现最大与最小值在每一级
2. 构建的高斯金字塔,每一层根据sigma的值不同,可以分为几个等级,最少有4 个。
关键点定位
在像素级别获得了极值点的位置,但是更准确的 值应该在亚像素位置,如何得到 – 这个过程称为关键 点(准确/精准)定位。
删除弱边缘- 通过Hassian 矩阵特征值实现,小于阈值 自动舍
关键点方向指定
求得每一层对应图像的梯度,根据给定的窗口大小
计算每个高斯权重,sigma=scalex1.5, 0~360之间建立 36个直方图Bins
找最高峰对应的Bin, 大于max*80% 的都保留 。这样就实现了旋转不变性,提高了匹配时候的稳定性。
大约有15%的关键点会有多个方向。
关键点描述子
拟合多项式插值寻找最大Peak
得到描述子 = 4x4x8=128
cv::xfeatures2d::SIFT::create(
int nfeature=0,
int nOctaveLayers=3,
double contrastThreshold=0.04,
double edgeThreshold=10,
double sigma=1.6
)
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <iostream>
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
int main(int argc, char** argv) {
Mat src = imread("D:/vcprojects/images/test.png", IMREAD_GRAYSCALE);
if (src.empty()) {
printf("could not load image...
");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
int numFeatures = 400;
Ptr<SIFT> detector = SIFT::create(numFeatures);
vector<KeyPoint> keypoints;
detector->detect(src, keypoints, Mat());
printf("Total KeyPoints : %d
", keypoints.size());
Mat keypoint_img;
//绘制
drawKeypoints(src, keypoints, keypoint_img, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
namedWindow("SIFT KeyPoints", CV_WINDOW_AUTOSIZE);
imshow("SIFT KeyPoints", keypoint_img);
waitKey(0);
return 0;
}