OpenCV——SIFT特征检测

算法描述

       SIFT特征不只具有尺度不变性,即使改变旋转角度,图像亮度或拍摄视角,仍然能够得到好的检测效果。整个算法分为以下几个部分:

建立尺度空间,寻找极值

       构建图像高斯金字塔,求取DOG,在每一级发现最大与最小值

       构建的高斯金字塔,每一层根据sigma的值不同,可以分为几个待级,最少有4个。

关键点定位

       我们在像素级别获得了极值点的位置,但是更准确的值应该在亚像素位置,如何得到--这个过程称为关键点(准确/精确)定位。

       删除弱边缘--通过Hassian矩阵特征值实现,小于阈值自动舍弃。

关键点方向指定

       求得每一层对应图像的梯度,根据给定的窗口大小

       计算每个高斯权重,sigma=scale*1.5, 0-360之间建立36个直方图Bins

       找最高峰对应的Bin,大于max*80%的都保留

       这样就实现了旋转不变性,提高了匹配时候的稳定性

       大约有15%的关键点会有多个方向

关键点描述子

       拟合多项式插值寻找最大Peak

       得到描述子 = 4*4*8=128

哪些点是SIFT中要查找的关键点(特征点)?
       这些点是一些十分突出的点不会因光照条件的改变而消失,比如角点、边缘点、暗区域的亮点以及亮区域的暗点,既然两幅图像中有相同的景物,那么使用某种方法分别提取各自的稳定点,这些点之间会有相互对应的匹配点。
所谓关键点,就是在不同尺度空间的图像下检测出的具有方向信息的局部极值点。
根据归纳,我们可以看出特征点具有的三个特征:
                                                                        尺度 方向 大小

SIFT特征提取的缺点

  • 实时性不高,因为要不断地要进行下采样和插值等操作;
  • 有时特征点较少(比如模糊图像);
  • 对边缘光滑的目标无法准确提取特征(比如边缘平滑的图像,检测出的特征点过少,对圆更是无能为力)。

SIFT特征提取可以解决的问题:
目标的自身状态、场景所处的环境和成像器材的成像特性等因素影响图像配准/目标识别跟踪的性能。而SIFT算法在一定程度上可解决:
- 目标的旋转、缩放、平移(RST)
- 图像仿射/投影变换(视点viewpoint)
- 光照影响(illumination)
- 目标遮挡(occlusion)
- 杂物场景(clutter)

 

API

SIFT对象创建函数API

static Ptr<SIFT> features2d::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

features2d::SIFT::detect(  
              InputArray image,     
              vector<KeyPoint>& keypoints,
              InputArray mask=noArray() 
                               );
  • image 待检测的图像
  • keypoints 检测到的关键点集合
  • mask 指定在哪里寻找关键点的掩码(必须是在感兴趣区域中具有非零值的8位整数矩阵

SIFT绘制关键点函数API

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<opencv2/features2d.hpp>
#include<vector>
using namespace std;
using namespace cv;
int main()
{
    Mat img = imread("tahiti.jpg");

    Ptr<Feature2D> sift = SIFT::create();

    vector<KeyPoint> keypoints;

    Mat descriptors;

    sift->detectAndCompute(img, noArray(), keypoints, descriptors);

    drawKeypoints(img, keypoints, descriptors, cv::Scalar::all(-1));

    imshow("Result", descriptors);
    waitKey(0);
    return 0;
}

代码示例:

 SIFT特征提取的缺点暴露无余,对于过于平滑的边缘无法提取. 些许模糊的图像也会造成很大的影响。(例如下面的草地,远处的山和蓝天)

 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DDsoup

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值