Lowe提出的SIFT(Scale Invariant Feature Transform)是计算机视觉里影响力非常大的一个算法,其使用LOG的近似算法DOG(Difference of Gaussians)实现快速特征检测,然后对待选点进行位置的精调和筛选,最后考察其邻域,获得特征的矢量性描述。
SIFT特征效率高(优化后能达到实时的效果),具有尺度不变性、旋转不变性、部分的仿射不变性。
总的来说,SIFT主要分为以下4个步骤[1]:
(1)尺度空间极值检测:搜索所有尺度上的图像位置。通过高斯微分函数(近似)来识别潜在的对于尺度和旋转不变的兴趣点。
(2)关键点的定位:在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。
(3)方向的确定:基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。
(4)关键点描述:在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。
尺度空间极值检测
出发点与LOG一样,为了使特征具有尺度不变性。
SIFT首先建立图像金字塔:将金字塔分成O组,每一组称为一个Octave;每一个Octave又分成S层,每层的图像是由不同方差的高斯滤波器滤波的结果(越往上图像越模糊);每一个Octave的底层图像由上一个Octave的第S层图像高宽下2采样得到(缩小1/4);然后对高斯塔相邻两层做差得到DOG响应金字塔(是对LOG的近似)
图1-1. 图像金字塔
如图1-1,由图片大小决定Octave的数目(Rob Hess代码默认当图片缩小到4个像素则停止),每Octave的层数设为3-5层(代码默认3);对于第 i 个(i=1...)Octave的第 n 层(n=1...S)图片,其对应的高斯尺度为,其中,sita一般预设为1.6。在实际中,为了保证上一组Octave与当前Octave的连续性,需要对每Octave的顶层再加3层,也就是实际上每一Octave的层数为S+3(假设S=3,对第1个Octave,gauss塔尺度为σ, kσ, k2σ, DoG塔尺度为σ, kσ,而DOG空间中的极值比较需要3层,因此考虑加上3层,这样第1个Octave的DOG空间尺度为 σ, kσ, k2σ, k3σ,k4σ,第2个Octave的DOG空间尺度为 2σ, 2kσ, 2k2σ, 2k3σ, 2k4σ,进行极值比较时底层和顶层无法计算,由于2 * k3σ = 2kσ 实现了尺度变化的连续性)
SIFT尺度空间的极值检测在DOG塔里进行,对每个点,比较其相邻的26个点,若为最大或最小值则记为待选极值点
通常需要将原始图像做高斯平滑(σ = 0.5),考虑到因此损失的高频信息,第1Octave的第1层为原始图像resize 2倍再平滑的结果,这样建立高斯塔的高斯尺度为
关键点的定位
(1)对于DOG金字塔的每个点,(Rob Hess代码里先经过一次对比度阈值筛选)检测其邻近26个点,如果为极值则记为待选点;
(2)以上极值点是在离散空间中搜索的,SIFT对每个待选点,通过插值得到极值点再连续空间中的精确位置(包括 行,列,尺度):
令,f(x)为该向量在DOG空间中的响应,将其泰勒展开,有,其中,,对f(X)求导,取其导数为0时候的点,即为所求精确位置距当前位置的偏移向量:。当计算得到的偏移向量每一维都小于0.5时认为位置调整完毕。
(3)根据(2)更新的极值点位置及偏移向量,计算对应的DOG响应(理论上f(X)的极值),如果该响应小于给定阈值(0.03),认为其不够稳定,删除。
(4)过滤可能的边缘点。SIFT认为边缘点不好定位,并且易受噪声影响,因此需要去除。注意到边缘点在横跨边缘的地方有较大曲率,而在垂直边缘的方向有较小曲率。曲率通过DOG响应的Hessian矩阵求得(见DOH分析):,其两个特征值反映了x,y两个方向的长度,当两个特征值相等时特征区域为圆形,此时公式取最小值,其中。Lowe论文中取r=10,大于该式的特征将被去掉。
方向的确定及关键点描述
对每个特征点,需要根据公式计算其方向及该方向的强度。注意L表示在高斯空间的图像金字塔内计算。
为了获得稳定的方向,SIFT考虑当前点邻域内点的方向及强度,乘以高斯分布参数(近似圆形),并将方向离散化为45度(或10度)一柱,用8柱(36柱)的直方图描述邻域内所有点的方向,以此作为该特征点的方向描述(对8柱直方图,如果邻域半径为4,则该特征的方向特征维度为4*4*8=128),最后将方向特征向量归一化以排除光照影响,取最大的那个分量作为该关键点的主方向。
在这里一般还会对方向描述直方图做高斯平滑以弥补仿射带来的影响;还可以选取第二大的分量作为关键点的辅助方向。
在最后生成的关键点描述向量(128维)时,还需以其主方向为参考,旋转其它方向,以此来确保SIFT特征的旋转不变性
SIFT特征必有的内容就是匹配不同视角下同一特征,基本思想很简单,分别对两幅图做SIFT检测,一一计算特征向量的欧式距离。
但穷举法效率太低,Rob Hess代码中应用了KD树(K近邻的一种实现)组织特征向量,使用BBF算法进行查询,匹配效率达到实时的效果。
相应的算法分析见JULY博客
代码实现见大神Rob Hess的github项目,源码分析网上很多,比如masikkk的博客
需要说明的是,Rob代码里默认直方图是36柱,这样特征维数应该是4*4*36 = 576,但其宏定义里设置的维度为128,会造成泄露,改下定义就好了
贴两张Rob Hess代码得到的效果图(上为SIFT检测效果,下为match效果):
[1] http://underthehood.blog.51cto.com/2531780/658350
[2] http://blog.csdn.net/abcjennifer/article/details/7639681
[3] http://blog.sina.com.cn/s/blog_4bdb170b0101pumc.html
[4] http://blog.csdn.net/v_july_v/article/details/6246213