python+opencv之特征检测(SIFT 尺度不变特征变换)

 

目录

一、SIFT综述

二、sift算法详解                                        

1、尺度空间极值检测

1.1 尺度空间(Scale Space)思想 1962提出

1.2 尺度空间的数学表示

1.3 尺度空间的获取

1.4 极值检测

2、关键点定位

2.1 精确定位

2.2 去除边缘响应

3、方向匹配

4、关键点描述

三、opencv-python 编程

四、总结


                              

 

一、SIFT综述


尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量,此算法由 David Lowe在1999年所发表,2004年完善总结。

其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。

此算法有其专利,专利拥有者为英属哥伦比亚大学。

局部影像特征的描述与侦测可以帮助辨识物体,SIFT 特征是基于物体上的一些局部外观的兴趣点而与影像的大小和旋转无关。对于光线、噪声、些微视角改变的容忍度也相当高。基于这些特性,它们是高度显著而且相对容易撷取,在母数庞大的特征数据库中,很容易辨识物体而且鲜有误认。使用 SIFT特征描述对于部分物体遮蔽的侦测率也相当高,甚至只需要3个以上的SIFT物体特征就足以计算出位置与方位。在现今的电脑硬件速度下和小型的特征数据库条件下,辨识速度可接近即时运算。SIFT特征的信息量大,适合在海量数据库中快速准确匹配。

SIFT算法的特点有:

  • SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性;
  • 独特性(Distinctiveness)好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配;
  • 多量性,即使少数的几个物体也可以产生大量的SIFT特征向量;
  •  高速性,经优化的SIFT匹配算法甚至可以达到实时的要求;
  •  可扩展性,可以很方便的与其他形式的特征向量进行联合。

SIFT算法可以解决的问题:

目标的自身状态、场景所处的环境和成像器材的成像特性等因素影响图像配准/目标识别跟踪的性能。而SIFT算法在一定程度上可解决:

  • 目标的旋转、缩放、平移(RST)
  • 图像仿射/投影变换(视点viewpoint)
  • 光照影响(illumination)
  • 目标遮挡(occlusion)
  • 杂物场景(clutter)
  • 噪声

SIFT算法的实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。 

Lowe将SIFT算法分解为如下四步:

  • 尺度空间极值检测:搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。
  • 关键点定位:在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。
  • 方向确定:基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。
  • 关键点描述:在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。

————————————————
原文链接:https://blog.csdn.net/zddblog/article/details/7521424

二、sift算法详解                                        

我们看到了一些像Harris这样的角检测器。它们是旋转不变的,这意味着即使图像旋转了,我们也可以找到相同的角。很明显,因为转角在旋转的图像中也仍然是转角。但是缩放呢?如果缩放图像,则角可能不是角。例如,检查下面的简单图像。当在同一窗口中放大图像时,在小窗口中的小图像中的角是平坦的。因此,Harris角不是尺度不变的。

                                                python+opencv之特征检测(SIFT 尺度不变特征变换)_第1张图片  

1、尺度空间极值检测

看到这两个名词,相信大多数刚刚接触的同学一阵头大,其实大家不用这么害怕。

我是这样分析的,对于第一步,我们要解决两个问题:一是什么是尺度空间,二是极值检测是为了什么

1.1 尺度空间(Scale Space)思想 1962提出

  • 尺度空间理论基本思想:在图像信息处理模型中引入一个被视为尺度的参数,通过连续变化尺度参数获得多尺度下的尺度空间表示序列,对这些序列进行尺度空间主轮廓的提取,并以该主轮廓作为一种特征向量,实现边缘、角点检测和不同分辨率上的特征提取等。
  • 说白了就是,一张原图片,进行缩放,但并不是我们常见的那种缩放,它是像素级别的缩放,比如1024*1024大小的图片,缩小后图片变为512*512(1024*1024 512*512 就是尺度),相当于丢失了很多像素信息,然后经过几次缩放,就会得到一个图片序列,里面是不同尺度的图片,排列起来就像一个金字塔,之后的高斯金字塔也是因此得名。
  • 而尺度空间就是指的是这个图像序列。然后我们对这个图像序列每张图片进行图像特征提取,就能完整找到该图片的本质特征。说白了,尺度空间就相当于我们人眼看物体的感觉,由近及远,越来越模糊
  • 尺度空间满足视觉不变性。该不变性的视觉解释如下:当我们用眼睛观察物体时,一方面当物体所处背景的光照条件变化时,视网膜感知图像的亮度水平和对比度是不同的,因此要求尺度空间算子对图像的分析不受图像的灰度水平和对比度变化的影响,即满足灰度不变性和对比度不变性。另一方面,相对于某一固定坐标系,当观察者和物体之间的相对位置变化时,视网膜所感知的图像的位置、大小、角度和形状是不同的,因此要求尺度空间算子对图像的分析和图像的位置、大小、角度以及仿射变换无关,即满足平移不变性、尺度不变性、欧几里德不变性以及仿射不变性。

1.2 尺度空间的数学表示

一个图像的尺度空间,定义为一个变化尺度的高斯函数与原图像的卷积。

 

其中,*表示卷积运算,

 

与公式相同,m,n表示高斯模板的维度(由确定)。(x, y)代表图像的像素位置。是尺度空间因子,值越小表示图像被平滑的越少,相应的尺度也就越小。大尺度对应于图像的概貌特征,小尺度对应于图像的细节特征。

1.3 尺度空间的获取

尺度空间一般是由高斯金字塔来构建的:

  • 对图像做不同尺度的高斯模糊
  • 对图像做降采样

python+opencv之特征检测(SIFT 尺度不变特征变换)_第2张图片

将图像金字塔每层的一张图像使用不同参数做高斯模糊,使得金字塔的每层含有多张高斯模糊图像,将金字塔每层多张图像合称为一组(Octave),金字塔每层只有一组图像,组数和金字塔层数相等, 

 高斯金字塔和高斯差分金字塔:

  • 高斯金字塔:高斯拉普拉斯函数(Laplacion of Gaussian,LoG算子)
  • 高斯差分金字塔:高斯差分函数(Difference of Gaussian DOG算子)
  • 高斯差分函数比高斯拉普拉斯函数更高效
  • 高斯差分金字塔是由高斯金字塔上下两层相减得来的

python+opencv之特征检测(SIFT 尺度不变特征变换)_第3张图片

 

python+opencv之特征检测(SIFT 尺度不变特征变换)_第4张图片

1.4 极值检测

关键点是由DOG空间的局部极值点组成的,关键点是通过同一组内各DoG相邻两层图像之间比较完成的。为了寻找DoG函数的极值点,每一个像素点要和它所有的相邻点比较,看其是否比它的图像域和尺度域的相邻点大或者小。

如下图所示:中间的检测点要和同尺度的8个点和上下两个尺度的各9个点,一共26个点相比较,如果该点是局部极值,则其可能是关键点。

python+opencv之特征检测(SIFT 尺度不变特征变换)_第5张图片

极值检测的目的就是找到那些可能是关键点的极值点集合,这些关键点中就有尺度不变和旋转不变的特性,而这个特性就是最后我们要找的图像的特征。

2、关键点定位

关键点定位主要解决两个问题,一是精确定位关键点的位置和尺度,二是由于DoG对边缘的响应较高,因此需要去除边缘

2.1 精确定位

离散空间的极值点并不是真正的极值点,下图显示了二维函数离散空间得到的极值点与连续空间极值点的差别。利用已知的离散空间点插值得到的连续空间极值点的方法叫做子像素插值(Sub-pixel Interpolation)。

python+opencv之特征检测(SIFT 尺度不变特征变换)_第6张图片

为了提高关键点的稳定性,需要对尺度空间DoG函数进行曲线拟合。利用DoG函数在尺度空间的Taylor展开式(拟合函数)为:

求上式导数为0,得到函数的极值点和其对应函数值,然后 和离散空间的极值点比较,若偏移量大于0.5,则需要重新插值,不断迭代,直至符合要求。同时若该点强度小于0.3,则该点就要删除。具体理论请看https://blog.csdn.net/zddblog/article/details/7521424

2.2 去除边缘响应

DoG对边缘的响应较高,因此也需要删除边缘。 为此,使用类似于哈里斯拐角检测器的概念。 他们使用2x2的Hessian矩阵计算主曲率。从哈里斯拐角检测器我们知道,对于边缘,对应的是一个特征值大于另一个特征值。

H的特征值α和β代表x和y方向的梯度,

表示矩阵H对角线元素之和,表示矩阵H的行列式。假设是α较大的特征值,而是β较小的特征值,令,则

把得到关键点带入上述式子,若符合不等式保留,反之剔除

 

3、方向匹配

为了使描述符具有旋转不变性,需要利用图像的局部特征为给每一个关键点分配一个基准方向。使用图像梯度的方法求取局部结构的稳定方向。对于在DOG金字塔中检测出的关键点点,采集其所在高斯金字塔图像3σ邻域窗口内像素的梯度和方向分布特征。梯度的模值和方向如下:

上式计算关键点梯度大小和方向

python+opencv之特征检测(SIFT 尺度不变特征变换)_第7张图片

方向直方图的峰值则代表了该特征点处邻域梯度的方向,以直方图中最大值作为该关键点的主方向。为了增强匹配的鲁棒性,只保留峰值大于主方向峰值80%的方向作为该关键点的辅方向。因此,对于同一梯度值的多个峰值的关键点位置,在相同位置和尺度将会有多个关键点被创建但方向不同。仅有15%的关键点被赋予多个方向,但可以明显的提高关键点匹配的稳定性。实际编程实现中,就是把该关键点复制成多份关键点,并将方向值分别赋给这些复制后的关键点,并且,离散的梯度方向直方图要进行插值拟合处理,来求得更精确的方向角度值

4、关键点描述

通过以上步骤,对于每一个关键点,拥有三个信息:位置、尺度以及方向。接下来就是为每个关键点建立一个描述符,用一组向量将这个关键点描述出来,使其不随各种变化而改变,比如光照变化、视角变化等等。这个描述子不但包括关键点,也包含关键点周围对其有贡献的像素点,并且描述符应该有较高的独特性,以便于提高特征点正确匹配的概率。 

SIFT描述子是关键点邻域高斯图像梯度统计结果的一种表示。通过对关键点周围图像区域分块,计算块内梯度直方图,生成具有独特性的向量,这个向量是该区域图像信息的一种抽象,具有唯一性。

三、opencv-python 编程

opencv中有专门的算法模块,编程其实是非常简单的,到其背后的原理就是很复杂的,上述就是为了让我们读者,能够看到算法的复杂性,对算法有一个更加深层的理解。

import numpy as np
import cv2 as cv

img = cv.imread('home.jpg')
gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)

sift = cv.xfeatures2d.SIFT_create()
kp = sift.detect(gray,None)
img=cv.drawKeypoints(gray,kp,img)

四、总结

  • 尺度空间极值检测就是找到所有可能是关键点的极值点
  • 关键点定位就是在这些极值点集合中更加精确的定位关键点,剔除那些不符合要求的极值点
  • 方向匹配就是在已知关键点的位置和尺度基础上,给关键点加上旋转不变的特性。使得该关键点符合尺度不变和方向不变 
  • 关键点描述就是给这些关键点生成一个特征向量,该特征向量中有关键点位置,尺度,和方向特性,为之后的图像匹配做基础

本文撰写过程中,借鉴了下面博客的大量内容,同时在其基础中也自己写了一点内容。我就厚脸皮的原创了。。。。
原文链接:https://blog.csdn.net/zddblog/article/details/7521424

你可能感兴趣的:(特征检测,OpenCV,Python学习)