前面提到了Harris角点检测,此方法一个很明显的缺点是不能解决尺度变化不变性,因为Harris中检测一个点是不是角点是看这个点所在patch和周围各个方向patch是否有明显变化,可是尺度变化后这个方法不适用,SIFT利用差分高斯金字塔解决了这个问题。
SIFT特征点检测步骤:
(1)首先将图片构成高斯多尺度金字塔。每层都是上层通过下采样得到的。每层高斯金字塔中都有不同尺度因子(高斯中的标准差)的高斯模糊。然后为了计算图像的高斯拉普拉斯(LoG),利用差分高斯(DoG)实现,数学上可以证明DoG是近似LoG的,证明如下:
整个金字塔是如下形式:
图中左边是不同尺度的高斯金字塔,而右边是在左边高斯的情况下对不同尺度高斯之间进行差分,下一层的基础图是上层第三个尺度的高斯图。
(2)在得到差分高斯金字塔后,需要找到拉普拉斯高斯的极值点,也就是差分高斯的极值点,而且这个极值点不仅是此尺度下的极值点,也是相邻尺度高斯图中的极值点,所以每个点要和周围26个点进行比较差分高斯值,如下:
至此选择了特征点的候选点。
(3)最后通过考虑消除边缘响应和消除对比度低的点来去掉一些点,然后用曲线拟合计算亚像素级别的极值点精确定位,最后得到特征点精确坐标。
SIFT特征点描述步骤:
要想进行特征点匹配需要知道特征点的描述向量。之前检测中能解决尺度变化问题,接下来想通过描述来解决旋转问题。旋转的解决方法是寻找一个主方向,这样其他方向可以根据离这个主方向的角度来确定。
(1)寻找主方向。在特征点附近的一个邻域(圆形区域)内计算每个点的梯度幅值和角度,根据角度作为横坐标计算直方图,直方图纵坐标为幅值的叠加,选取纵坐标最大的方向作为特征点的主方向。
(2)选取主方向后需要得到描述子,为了消除旋转影响,首先将特征点附近需要考虑的邻域根据主方向进行旋转:
然后将这个邻域分为四个子区域(也可以是16个),每个子区域包含4*4区域,每个像素都有梯度方向,利用直方图统计每个子区域在8个方向的梯度值大小的统计值:
这样每个子区域就有8维的向量,连起来就是32维向量,如果是16个子区域就是128维向量,也就是SIFT描述子。
SIFT特征点匹配:
NNDR (NearestNeighbor Distance Ratio),也就是最近邻次近邻匹配。如果 某个特征点与最相近(描述子最相像)的一个特征点和次相近的特征点差不多,就不太好;如果差很多,也就是和最相近的特征点很相近,和次相近的特征点不太相近的话就说明和最相近的特征点匹配很好。