1.推荐/引用 博客
SIFT算法研究:http://underthehood.blog.51cto.com/2531780/658350
SIFT特征提取算法总结:http://www.cnblogs.com/cfantaisie/archive/2011/06/14/2080917.html
图像特征提取与匹配之SIFT算法:http://blog.csdn.net/v_JULY_v/article/details/6186942
一些公式推导来自实验室师兄的笔记,感谢。
论文:David G. Lowe, "Distinctive image features from scale-invariant keypoints,"
International Journal of Computer Vision, 60, 2 (2004), pp. 91-110
SIFT算法学习
1.算法流程
2.具体实现
(1)构造高斯差分尺度空间
高斯函数是唯一的尺度变换核,则图像的尺度空间就可以看做是尺度变换的高斯函数与输入图像的卷积。
其中,尺度可变的高斯核为
其中,(x,y)是空间坐标,σ是尺度坐标。σ 的大小决定图像的平滑程度,大尺度对应图像的概貌特征(低分辨率),小尺度对应图像的细节特征(高分辨率)。
为了有效在尺度空间检测到稳定的关键点,提出用不同尺度的高斯差分核与图像卷积:
其中k为常数,用来区分两相邻尺度乘积因子。
选择高斯差分尺度空间DOG的原因:
① 容易计算,为求出不同尺度上的图像特征,只需要作差就可以了;
② 高斯差分函数DOG近似于尺度归一化的LOG,相比于其他特征,LOG的最大最小值产生的特征更加稳定。
关于DOG近似归一化LOG的证明:
利用有限差分逼近:
在所有尺度上,k-1是常数,不影响极值点的位置,k越接近1,近似误差越接近0.但实际中发现这种近似对极值检测的稳定性和位置几乎不存在影响,甚至在尺度上发生较大变化时也一样。
高斯差分尺度空间的构造:
首先是构建图像的高斯金字塔。原始图像递增地与高斯函数卷积来生成新尺寸的图像,尺度空间中的图像由常数因子K来区别。
关于尺度空间的理解说明:上图是必须的,尺度空间是连续的。在Lowe的论文中 ,在最开始建立高斯金字塔时,要预先模糊输入图像来作为第0个组的第0层的图像,这样就会丢失高频信息。因此,为了充分利用输入图像可以首先对原始图像长宽扩展一倍,来增加特征点数量。尺度越大图像越模糊。 我们利用线性插值将图像扩大为原来2倍,作为金字塔的第一层。
图像金字塔共分O组,一组称为一个Octave,每组又分为多层,层间隔数为S,因此有S+3(S+1+2,2代表在上下再各添一层图像,搜索极值只在中间的S+1层图像上搜索)层图像,下一组的第一层图像由上一组的倒数第三层(如果层索引从0开始,则为第S层)图像按照隔点采样(试验中用3个尺度采样)得到,可减少卷积运算的工作量。
DoG是通过高斯金字塔中的每组上下相邻两层的高斯尺度空间图像相减得到。
(2)寻找尺度空间极值点
同一组中的相邻尺度(由于k的取值关系,肯定是上下层)之间进行寻找:在极值比较的过程中,每一组图像的首末两层是无法进行极值比较的,为了满足尺度变化的连续性,在每一组图像的顶层继续用高斯模糊生成了 3 幅图像,高斯金字塔有每组S+3层图像。DOG金字塔每组有S+2层图像.
(3)精确定位极值点
① 对检测到的极值点进行三维二次函数拟合,精确定位极值点的位置和尺度,达到亚像素精度。
极值点的搜索是在离散空间中进行的,检测到的极值点并不是真正意义上的极值点。二维函数离散空间得到的极值点与连续空间极值点有差别。利用已知的离散空间点插值得到的连续空间极值点的方法叫做子像素插值.
插值的方法是根据泰勒级数展开:
求导,并令其为0,得到极值点位置的偏移量:
x^代表相对于插值中心的偏移量,当它在任一维度上的偏移量大于0.5时(即x或y或σ),意味着插值中心已经偏移到它的邻近点上,所以必须改变当前关键点的位置(加上x^)同时在新的位置上反复插值直到收敛;也有可能超出所设定的迭代次数或者超出图像边界的范围,此时这样的点应该删除。
② 去除低对比度的点
极值点的函数值:
回代:
得:
极值点的函数值可以用来去除由低对比度造成的不稳定极值,在该文章中,若极值点函数值小于0.03,则表明其响应值过小易受噪声影响而变得不稳定,要去除.
③ 去除边缘相应
高斯差分函数DOG对边缘有着很强的响应,边缘上的点对于小的噪声不稳定。根据Harris角点可以知道,一个角点在任何方向上平移都应该保证局部窗口内的像素值的剧烈变化,而边缘上的点沿着边缘方向移动时局部窗口内的像素值基本没有什么变化。
一个平坦的(边缘点)DoG响应峰值往往在横跨边缘的地方有较大的主曲率,而在垂直的方向有较小的主曲率。所以利用主曲率比的大小来排除边缘响应的点。而主曲率可以通过2×2的Hessain矩阵H求出:
H的特征值与D的主曲率成正比例。我们只关心比例,可以不必明确地计算特征值,可以由H的迹和行列式的积来计算特征值的和。令α为大的特征值,β为小的特征值,则主曲率的比值大小可由特征值所表示的比值式来计算:
试验中,该比例大于10的点被认为是边缘点,应去除。
(4)给每个关键点分配主方向
利用关键点邻域像素的梯度方向分布特性(幅值和方向)为每个关键点指定方向参数,使算子具备旋转不变性。
其中L所用的尺度为每个关键点各自所在的尺度。
在完成特征点邻域的高斯图像的梯度计算后,使用直方图统计邻域内像素的梯度方向和幅值。梯度方向直方图的横轴是梯度方向角,纵轴是梯度方向角对应的梯度幅值累加。梯度方向直方图将0-360度的范围分为36个柱(bins),每10度一个柱。
高斯加权函数(o为描述子窗宽的一半)用来对每个采样点的幅值进行加权,距离描述子中心越远的领域对直方图的贡献也响应也越小,可以避免窗口位置变化引起的描述子突变。
直方图的峰值代表该特征点处邻域内图像梯度的主方向,也即该特征点的主方向。
当存在一个相当于主峰值能量80%能量的峰值时,会产生一个具有该主方向的极值点。因此,对于具有相似幅值的多峰位置点,会在一个位置上产生多个关键点。只有15%的点会有多个方向,但是这对匹配影响很大。最终,用抛物线来拟合3个接近峰值的直方图的值进行峰值点位置插值,获得更好的准确性。
(5)特征描述子生成
每一个小格都代表了特征点邻域所在的尺度空间的一个像素 ,箭头方向代表了像素梯度方向,箭头长度代表该像素的幅值。然后在4×4的窗口内计算8个方向的梯度方向直方图。绘制每个梯度方向的累加可形成一个种子点。
每个直方图有8方向的梯度方向,每一个描述符包含一个位于关键点附近的四个直方图数组.这就导致了SIFT的特征向量有128维.(先是一个4×4的来计算出一个直方图,每个直方图有8个方向。所以是4×4×8=128维)
为避免边界影响,采用三线性插值,将每一个梯度样本值分配到相邻的直方图块中。每一个直方图块在每个维上乘以权重1-d,d是样本到直方图块中心值的距离。
&实现光照不变性
① 处理线性变化(对比度/亮度):归一化到单位向量
为了降低光照变化的影响:首先,特征向量归一化到单位长度,每个像素值乘以一个常数引起图像对比度的改变,会使梯度乘以相同的常数。所以归一化后会撤销常数的改变。亮度变化引起的每个像素值增加一个常数,不会影响梯度值。因此该描述子具有光照不变性。
② 处理非线性变化(饱和度/光照):归一化+阈值化+归一化
相机饱和度或光照变化影响3D表面的方向变化,这些影响会使梯度幅值有大的改变,但不太会影响梯度方向。因此要降低大的梯度幅值的影响,将单位特征向量进行阈值化:对于中值大于0.2的要进行截断,即大于0.2的值只取0.2,再进行一次归一化处理,其目的是提高特征的鉴别性。