身为菜鸟的我,花了将近3个月的时间把sift算法吃透并自己把算法实现啦,实在是耗时耗力呀,为了对得起我这段时间的努力,决定把自己对sift算法的理解和大家分享一下,有什么错误望各位大神指教,小妹在此献丑啦。
一 概念
sift---Scale Invariant Feature Transform,尺度不变特征匹配变换算法。sift特征对旋转、尺度缩放、亮度变化等具有不变性,是非常稳定的局部特征。
二 主要思路
构造图像尺度空间表示-----尺度空间中搜索图像的极值点----由极值点建立特征描述向量-----用特征描述向量进行相似度匹配。
1、详细讲解
(1) 构建LOG图像
这里有两个概念需要区分清楚:金字塔多分辨率、图像的多尺度空间。
多尺度空间表示由不同的高斯核平滑卷积得到(即此步骤所做之事),在所有尺度上具有相同的分辨率。而金字塔多分辨率表示每层分辨率减少固定比例。
图像尺度空间的形成是通过将图像与具有可变核的高斯滤波器进行卷积, 从而得到图像的高斯金字塔 LoG。高斯卷积核是实现尺度变换的唯一线性变换核,一幅图像在尺度空间中可表示为图像和可变高斯核函数的卷积,采用高斯金字塔(Laplacian of Gaussian,LoG )算子表示如下:
L(x, y,σ ) = G(x, y,σ ) ⊗ I(x, y)
其中, I(x,y) 为输入的二维图像, 为可变高斯核函数, σ 为可变核。
David指出,高斯金字塔 LoG 共分为O 组,每组 S +3 层, S 为σ 与 2σ 之间的层数, S 一般取 2 或 3。在这里我们构建5层多尺度空间,即S=2。
高斯金字塔组数一般为:
O=[log2min(m,n)]-3
m,n分别表示图像的行和列。
高斯模糊参数σ,计算公式如下:
σ(o,s)=σ0*2(o+s)/S
其中,σ0为初始尺度因子,S为每组层数,s为每组内具体哪一组。在罗伊的算法实现中,以上参数的取值为:σ0=1.6*21/S,相邻组间尺度关系:σo+1=2σo
总结:相邻两组的同一层尺度为2倍的关系。相邻层之间为k倍的关系。k=21/S,S为每组的的层数。在我们的程序中S为2。
构建步骤:
1)先将采集到的图扩大为原图的两倍,称为I。
2)对I进行高斯滤波,形成不同尺度下(即σ不同)的5(S +3)张(层)高斯模糊图像,这称为金字塔的第1组图像。如下图所示:
σ大小决定图像的平滑程度,大尺度对应图像的概貌特征,小尺度对应图像的细节特征。大的σ值对应粗糙尺度(低分辨率),反之,对应精细尺度(高分辨率)。
3)第2组图像的第一层由第1组的倒数第3层图像降采样(尺寸缩小一半,即水平、竖直方向1/2)得到,然后重复2)得到第2组图像,同理可得到其他组图像。
经过模糊与降采样,最终得到图像:
(2) 构建DoG图像
DoG--Difference of Gaussian,差分金字塔。DoG算子定义为两个不同尺度的高斯核的差分,它是归一化高斯拉普拉斯(LoG)算子的近似。很多资料都有介绍,所以原理在这里将不详细介绍。DoG算子定义如下:
D(x,y,σ ) = (G(x, y,kσ ) − G(x, y,σ ) ⊗ I(x,y) = L(x, y,kσ ) − L(x, y,σ )
其中,因子 k 满足 k =21/ S。
在实际计算时,使用高斯金字塔每组中相邻上下两层图像相减,得到高斯差分图像,如图3.3所示,进行极值检测。
(3) 空间极值检测
检测DOG局部极值点。使用Laplacianof Gaussian能够很好地找到找到图像中的兴趣点,但是需要大量的计算量,所以使用Differenceof Gaussian图像的极大极小值近似寻找特征点DOG算子计算简单,是尺度归一化的LoG算子的近似。
寻找DoG极值点时,每一个像素都需要和与它同一尺度以及相邻尺度的所有邻域点相比较,当其大于或小于它的图像域和尺度域的所有相邻点时,即为极值点。如图:
中间的检测点(打X)和它同尺度的8个相邻点和上下相邻尺度对应的9×2个点共26个点比较,以确保在尺度空间和二维图像空间都检测到极值点。
s=3的情况
由于首层和末层都缺少一个邻近层,因此搜索从每组的第二层开始,以第二层为当前层,第一层和第三层分别作为立方体的上下层,搜索完成后再以第三层作为当前层做同样的搜索。所以每层的点搜索两次。
解释一下:为什么上边提到,每一组中生成的层数是S+3层呢?
其实层数确实是3层,但是为了为了满足尺度变化的连续性,我们在每一组图像的顶层继续用高斯模糊生成了 3 幅图像,高斯金字塔有每组S+3层图像。DOG金字塔每组有S+2层图像.
这里不理解什么叫“为了满足尺度变化的连续性”,现在做仔细阐述:
假设s=3,也就是每个塔里有3层,则k=21/s=21/3,那么按照上图可得GaussSpace和DoGspace 分别有3个(s个)和2个(s-1个)分量,在DoGspace中,1st-octave两项分别是σ,kσ;2nd-octave两项分别是2σ,2kσ;由于无法比较极值,我们必须在高斯空间继续添加高斯模糊项,使得形成σ,kσ,k2σ,k3σ,k4σ这样就可以选择DoGspace中的中间三项kσ,k2σ,k3σ(只有左右都有才能有极值),那么下一octave中(由上一层降采样获得)所得三项即为2kσ,2k2σ,2k3σ,其首项2kσ=24/3。刚好与上一octave末项k3σ=23/3尺度变化连续起来,所以每次要在Gaussianspace添加3项,每组(塔)共S+3层图像,相应的DoG金字塔有S+2层图像。
(4) 特征点定位
以上方法检测到的极值点是离散空间的极值点,通过拟和三维二次函数以精确确定关键点的位置和尺度(达到亚像素精度),同时去除低对比度的关键点(对噪音敏感)和不稳定的边缘响应点(定位在边角)(因为DoG算子会产生较强的边缘响应),以增强匹配稳定性、提高抗噪声能力,在这里使用近似HarrisCorner检测器。
1)关键点的精确定位
利用已知的离散空间点插值得到的连续空间极值点的方法叫做子像素插值(Sub-pixelInterpolation)。
为了提高关键点的稳定性,需要对尺度空间DoG函数进行曲线拟合。利用DoG函数在尺度空间的Taylor展开式(拟合函数)为:
通过多次迭代得到最终候选点的精确位置及尺度 ,将其带入下列公式
可求出。
其中, 代表相对插值中心的偏移量,当它在任一维度上的偏移量大于0.5时(即x或y或 ),意味着插值中心已经偏移到它的邻近点上,所以必须改变当前关键点的位置。同时在新的位置上反复插值直到收敛;也有可能超出所设定的迭代次数或者超出图像边界的范围,此时这样的点应该删除,在Lowe中进行了5次迭代。另外, 过小的点易受噪声的干扰而变得不稳定,所以将 小于某个经验值(Lowe论文中使用0.03,Rob Hess等人实现时使用0.04/S)的极值点删除。
具体过程:
b) 在已经检测到的特征点中,要去掉低对比度的特征点和不稳定的边缘响应点。去除低对比度的点:把公式(2)代入公式(1),即在DoG Space的极值点处D(x)取值,只取前两项可得:
若 ,该特征点就保留下来,否则丢弃。
2)消除边缘响应
由于DoG对图像中的边缘有比较强的响应值,而一旦特征落在图形的边缘上,这些点就是不稳定的点。根据Harris[4]角点可以知道,一个角点在任何方向上平移都应该保证局部窗口内的像素值的剧烈变化,而边缘上的点沿着边缘方向移动时局部窗口内的像素值基本没有什么变化。如下图所示:
同样,一个平坦的DoG响应峰值往往在横跨边缘的地方有较大的主曲率,而在垂直的方向有较小的主曲率。而主曲率可以通过2×2的Hessain矩阵H求出:
导数由采样点相邻差估计得到。
D的主曲率和H的特征值成正比,可以避免求取具体的特征值,因为我们只关心特征值的比例。H的特征值α和β代表x和y方向的梯度,则
Tr(H)表示矩阵H对角线元素之和,Det(H)表示矩阵H的行列式。假设是α较大的特征值,而是β较小的特征值,令α=γβ,则
D的主曲率和H的特征值成正比,令为α最大特征值,β为最小的特征值,则公式 的值在两个特征值相等时最小,随着的增大而增大。值越大,说明两个特征值的比值越大,即在某一个方向的梯度值越大,而在另一个方向的梯度值越小,而边缘恰恰就是这种情况。所以为了剔除边缘响应点,需要让该比值小于一定的阈值,因此,为了检测主曲率是否在某域值r下,只需检测
式(4-7)成立时将关键点保留,反之剔除。在Lowe的文章中,取r=10。
(5) 特征方向赋值
为了实现图像旋转的不变性,需要根据检测到的特征点的局部图像结构求得一个方向基准。我们使用图像梯度的方法求取该局部结构的稳定方向。对于已经检测到特征点,我们知道该特征点的尺度值 ,因此根据这一尺度值,得到最接近这一尺度的高斯图像:
L(x,y)=G(x,y, )*I(x,y)
使用有限差分,计算以特征点为中心,以3x1.5 为半径的区域内图像梯度的幅角和幅值计算公式如下:
L为关键点所在的尺度空间值,按Lowe的建议,梯度的模值m(x,y)按 的高斯分布加成(即高斯模板的σ为关键点的尺度的1.5倍),按尺度采样的3σ原则,邻域窗口半径为
。
每个加入梯度方向直方图的采样点梯度幅值都要进行权重处理,加权采用圆形高斯加权函数,其σ值为特征点尺度的1.5倍,由于sift算法只考虑了尺度和旋转的不变性,并没有考虑仿射不变性。通过高斯加权,使特征点附近的梯度幅值有较大的权重,这样可以部分弥补因没有仿射不变性而产生的特征点不稳定的问题
在完成关键点的梯度计算后,使用直方图统计邻域内像素的梯度方向和幅值。梯度直方图的横轴是梯度方向角,纵轴是梯度方向角对应的梯度幅值累加值。梯度直方图将0~360度的方向范围分为36个柱(bins),其中每柱10度。如图5.1所示,直方图的峰值方向代表了关键点的主方向,(为简化,图中只画了八个方向的直方图)。
方向直方图的峰值则代表了该特征点处邻域梯度的方向,以直方图中最大值作为该关键点的主方向。为了增强匹配的鲁棒性,只保留峰值大于主方向峰值80%的方向作为该关键点的辅方向。因此,对于同一梯度值的多个峰值的关键点位置,在相同位置和尺度将会有多个关键点被创建但方向不同。仅有15%的关键点被赋予多个方向,但可以明显的提高关键点匹配的稳定性。 |
至此,将检测出的含有位置、尺度和方向的关键点即是该图像的SIFT特征点。
解析:梯度的求取在特征点对应的高斯图像(LOG图像)上。
(6) 特征点特征矢量(方向描述子)生成
至此,我们确定了特征点的位置、尺度和方向,接下来为每个特征建立特征描述符,即使用一组向量将这个关键点描述出来,这个描述子不但包括关键点,也包括关键点周围对其有贡献的像素点。描述子不随各种变化而改变,比如光照、视角、环境变化等。
描述子将被用来作为目标匹配的依据(所以特征描述符应该有较高的独特性,以便于减小特征点的误匹配率)。
特征描述符大致包含三个步骤,即校正旋转主方向、生成描述子、归一化处理。其中旋转主方向就是将坐标轴旋转为关键点的方向,以确保旋转不变性。
描述子与特征点所在的尺度有关,因此对梯度的求取应在特征点对应的高斯图像上进行。
首先将坐标轴旋转为关键点的方向,以确保旋转不变性。将关键点周围分成dxd个子区域,每个子区域尺寸为mσ个像元(d=4,m=3, σ为特征点的尺度值)。
考虑到实际计算时需要进行双线性插值,所以计算的图像区域为mσ(d+1),再考虑旋转,实际计算的矩形区域边长为mσ(d+1) ,如图所示:
为了保证特征矢量具有旋转不变性,要以特征点为中心,在附近邻域内旋转θ角,即旋转为特征点的方向。实际计算所需的图像区域半径为:
计算结果四舍五入取整。
旋转后邻域内采样点的新坐标为:
旋转好后,以关键点为中心取8×8的窗口。
Figure.16*16的图中其中1/4的特征点梯度方向及scale,右图为其加权到8个主方向后的效果
图左部分的中央为当前关键点的位置,每个小格代表关键点邻域所在尺度空间的一个像素,利用公式求得每个像素的梯度幅值与梯度方向,箭头方向代表该像素的梯度方向,箭头长度代表梯度模值,然后用高斯窗口对其进行加权运算。
图中蓝色的圈代表高斯加权的范围(越靠近关键点的像素梯度方向信息贡献越大)。然后在每4×4的小块上计算8个方向的梯度方向直方图,绘制每个梯度方向的累加值,即可形成一个种子点,如图右部分示。此图中一个关键点由2×2共4个种子点组成,每个种子点有8个方向向量信息。这种邻域方向性信息联合的思想增强了算法抗噪声的能力,同时对于含有定位误差的特征匹配也提供了较好的容错性。
Lowe建议子区域的像素的梯度大小按 的高斯加权计算,即
其中a,b为关键点在高斯金字塔图像中的位置坐标。
此时每个子区域梯度方向直方图将0°~360°划分为8个方向区间,每个区间为45°,即每个种子点有8个方向区间的梯度强度信息。
在实际计算过程中,为了增强匹配的稳健性,特征点方向分配之后,接着生成特征描述子。以特征点为中心取 16×16 的窗口(特征点所在的行和列不取),每个小格代表特征点邻域所在尺度空间的一个像素,采用高斯加权(越靠近特征点的像素,梯度方向信息贡献越大)。在 4×4的图像小块上计算 8 个方向的梯度方向直方图,绘制每个梯度方向的累加值,形成一个种子点。
这样就可以对每个feature形成一个4*4*8=128维的描述子,每一维都可以表示4*4个格子中一个的scale/orientation. 将这个向量归一化之后,就进一步去除了光照的影响。
在归一化处理后,对于特征矢量中值大于0.2的要进行截断,即大于0.2的值只取0.2,然后再次进行归一化处理,其目的是为了提高特征的鉴别性。