SIFT特征检测介绍
SIFT(Scale-Invariant Feature Transform)特征检测关键特性
- 建立尺度空间,寻找极值
- 工作原理
- 构建图像高斯金字塔,求取DoG,发现最大与最小值在每一级
- 构建的高斯金字塔,每一层根据sigma值不同,可以分为几个等级,最少有四个
- 工作原理
- 关键点定位(寻找关键点准确位置与删除若边缘)
- 我们在像素级别获得了极值点的位置,但是更准确的值应该在亚像素位置,如何得到精确位置的过程称为关键点(准确、精准)定位
- 删除弱边缘-通过Hassian矩阵特征值实现,小于阈值自动舍弃
- 关键点方向指定
- 求得每一层对应图像的梯度,根据给定的窗口大小
- 计算每个高斯权重,sigma=scale*1.5~360之间建立36个直方图Bins
- 找最高峰对应的Bin,大于max*80%的都保留
- 这样就实现了旋转不变性,提高了匹配时候的稳定性
- 大约有15%的关键点会有多个方向
- 关键点描述子
- 拟合多项式差值寻找最大Peak
- 得到描述子=448=128
函数API
SIFT对象创建函数api
static Ptr<SIFT> cv::xfeatures2d::SIFT::create (
int nfeatures = 0,
int nOctaveLayers = 3,
double contrastThreshold = 0.04,
double edgeThreshold = 10,
double sigma = 1.6
)
参数介绍
- nfeatures 特征值数量保留的最佳功能的数量。这些特征按其分数排名(在SIFT算法中作为局部对比度测量)
- nOctaveLayers 高斯计算的层数
- contrastThreshold 用于过滤掉半均匀(低对比度)区域中的弱特征的对比度阈值。 阈值越大,检测器产生的特征越少。论文给出的值是0.3,opencv默认0.4区别不大
- edgeThreshold 用于过滤边缘特征的阈值。请注意,其含义与contrastThreshold不同,即edgeThreshold越大,滤除的特征越少(保留的特征越多)一般默认10。
- sigma 高斯的sigma应用于每层#0的输入图像。如果使用图像较弱,则可能需要减少数量。默认1.6
SIFT提取关键点函数api
void cv::xfeatures2d::SIFT::detect( InputArray image,
vector<KeyPoint>& keypoints,
InputArray mask=noArray()
);
函数参数介绍
- image 待检测的图像
- keypoints 检测到的关键点集合
- mask 指定在哪里寻找关键点的掩码(必须是在感兴趣区域中具有非零值的8位整数矩阵)
SIFT绘制关键点函数api
cv::drawKeypoints(InputArray image,
vector<KeyPoint>& keypoints,
InputOutputArray outImage,
const Scalar& color=Scalar::all(-1),
int flags=DrawMatchesFlags::DEFAULT
);
函数参数介绍
- image 进行绘制的图像
- keypoints 来自源图像的关键点
- outImage 绘制完成后输出图像
- color 关键点的颜色 默认值随机值
- DrawMatchesFlags 设置绘图功能的标志 默认圆圈
代码演示
#include <iostream>
#include <opencv2/opencv.hpp>
#include <math.h>
#include <opencv2/xfeatures2d.hpp>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
#define Pic_Path "C://pic//"
#define Pic_Name "3.jpg"
int main(void)
{
Mat src, dst, gray_src;
string pic = string(Pic_Path) + string(Pic_Name);
cout << "打开图片路径:" << pic << endl;
src = imread(pic);
if (src.empty())
{
cout << "图片不存在或打开失败" << endl;
return -1;
}
namedWindow("原始图片", WINDOW_AUTOSIZE);
imshow("原始图片", src);
//图片转换为灰度图像
cvtColor(src, gray_src, COLOR_BGR2GRAY);
//创建SURF对象
double hessianThreshold = 100; //检测阈值
vector<KeyPoint> keypoints; //关键点的集合
Ptr<SIFT> sift = cv::xfeatures2d::SIFT::create(hessianThreshold); //初始化SIFT对象
sift->detect(gray_src, keypoints); //检测关键点
printf("keypoints num is %d\n", keypoints.size());
dst = src.clone(); //拷贝原图 用于在原图上显示关键点
drawKeypoints(dst, keypoints, dst); //绘制关键点
//显示检测结果
namedWindow("SIFT检测图片", WINDOW_AUTOSIZE);
imshow("SIFT检测图片", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
运行效果
之前用SURF检测的效果
参考链接:https://blog.csdn.net/lingyunxianhe/article/details/79063547