« 相对论通俗演义贝叶斯分类器----分类器思想的起源 »

SIFT----Local 特征的经典之作

SIFT的整体思路还是用到滤波(由此可见滤波在图像处理中的重要性),利用滤波器产生的不同响应来进行对比处理,最终得到图像中物体的一些显著性的特征点。那既然提到了滤波,就一笔带过一下。

现在在图像处理中,对于物体一些特征的提取基本上都会想到滤波器。滤波器的功能就是使得固定频率的波段通过,而最大限度的抑制非该频率波段的信息。E.g 一个负无穷到正无穷频率的波,想要处理起来难度太大,同时也可能不少冗余信息,或者说是对于本次处理没有太多用处的信息。这个时候就可以分波段来处理。比如我提取20Hz~20kHz之间的频率(人类听力能力范围),怎样提取,就利用到滤波器(可以试低通滤波器,因为20Hz频率不是很高,当然也可以是带通滤波器)。

好了,滤波器稍带了一下,那先看下SIFT整个流程吧。
SIFT的步骤:
1. DOG层构造。
2. 局部极值点检测(包括各种删除)。
3. 特征点的梯度方向以及幅度的分配。
4. 描述子(点特征)的提取。

1. DOG层构造:
(1)分层(Octaves)利用高斯滤波器进行图像分尺度(different sigma in Gaussian Kernel)特征提取。(在Koenderink以及Lindeberg的文献中对多尺度有一个简单的说明,只有高斯核才能构建多尺度)
(2)利用高斯金字塔形式得到多尺度图像后,将相邻尺度的图像相减,即可以得到近似拉普拉斯变化的DOG(differential of Gaussian)图像组。(DOG算子近似拉普拉斯算子,都可以很好的对边缘做出检测,拉普拉斯算子速度上较慢,需要对图像两个方向做2次微分再求和。所以改用不分方向的高斯核卷积之后相减。)
  图1为原始高斯与DOG层:
SIFT----Local <wbr>特征的经典之作  SIFT----Local <wbr>特征的经典之作   SIFT----Local <wbr>特征的经典之作
图1 左边为不同octaves不同scale的高斯层  
右边为不同octaves的一些DOG层
    
2. 局部极值点检测:   
(1)此时经过实验或者理论验证都可以得出,在DOG层中有众多不同尺度相减得到的边缘图像,剩下的就是从这些边缘图像中得到候选特征点。方法:检测一个点是否比所在尺度图像的周围8个点都大或者小,这是在图像2维空间中的检测。另外还要检测该点是否比相邻尺度的同位置图像的9个点都大或者都小。如果该点比26点都大或者都小,则其是一个可选的特征点。
(2)极大极值点检测后,并非所有的点都是最值点。(高等数学中也有提到,极值点有可能非最值,同理,最值点也有可能非极值)所以这里又要用到插值(插值也会有很多方法,最小二乘的拟合......)。在SIFT中,直接在极值点处利用泰勒级数展开,并利用展开后的数值,得到一个二次方程。然后再利用二次方程进行拟合得到最值点。如果最终拟合得到的极值点小与某一个阈值则删除(考虑到真实环境会有各种各样的影响,如果最值点太小,而真实环境的影响又很大,那当然这个最值点就会受到很大的影响,所以为了在真实环境中有很好的泛化,必须有一个删除过程)。
图2解释为什么极值点不是最值点。
SIFT----Local <wbr>特征的经典之作     SIFT----Local <wbr>特征的经典之作
图2 离散极值点与最值点之间的关系

(3)边缘效应的删除能够更进一步的得到稳定的特征点。因为一个物体的边缘在不同的图像中或者在同一副图像中都可能会有变化。E.g. 一个正方形,在一幅图像中可以是两条水平线以及两条垂直的线组成,而在另一幅图像中,可以是有角度的旋转,类似于普通菱形。而其实它们都是同一个图像,如果利用边缘去做识别的话,因为4条边完全不一样,那就有可能识别错误。所以我们需要将这些边缘特征尽可能的删除,留下最具代表性的角上的点。在SIFT中,DOG算子近似拉普拉斯算子,对边缘都有很强的检测效果,那当然需要从这些特征点中删除哪些是具有强边缘效应的点。Lowe在2004年的文章中用到Hessian矩阵来做边缘点的删除。(利用Hessian矩阵来做边缘点的删除在Harri角点检测中有所应用,其目的也是为了降低速度的消耗)

 3. 特征点梯度的方向与幅度的分配(重要):     
其实前面也已经提到了,在做物体识别判断的时候,由于物体在不同的位置,或者物体在不同的图像中都会有很显著的变化,而能够较好保持这些显著变化的东西就是物体特征点附近的梯度幅度以及梯度大小了。试想一下,一台手机的4个角,不论将它怎样的摆放(保证4个角都有出现的情况下),边缘部分是会做刚体变化的(即旋转、长宽的变换),而4个角的梯度大小以及相对于物体的梯度方向的变化则是很小的,所以需要为每一个特征点分配梯度的方向以及幅度的大小。这一步的计算主要是针对各个特征点,对每一特征点带参进行单独的处理(即不同scale的图像,特征点所带的参数也是不一样的)。最终,利用得到的幅度大小,去做一个删选,因为一个点的梯度方向有可能不只一个,即很有可能会同时垂直于多条边,那这个时候利用一个梯度幅度的阈值来删除比这个阈值小的梯度。如果有比该阈值大且不是最大梯度的情况,将该点进行复制,同时新复制的点的梯度方向以及幅度分配为此时的情况。

4. 描述子的计算:
描述子的计算必须带有独特性。E.g. 如果两个特征点有相同的描述子,即独特性不强,那在匹配的时候这两个特征点会有很大的可能匹配到同一个点上,其实也可以理解为这两个特征点其实就是一个点。那怎样来描述一个特征点呢,从前面其实可以看到,用该点的梯度大小以及方向是最好的选择。首先将这些特征点的坐标旋转到梯度方向,然后在其周围选择一定量的统计量(包括周围点的梯度方向以及幅度),利用这样一些统计量得到一个多维的描述子。例如在大多数情况下,一个特征点的描述子是128维,具体看文献[1]以及一些code的实现。最终就可以得到一系列scale-invariant的特征描述子。在识别的过程中,也会这样计算特征点的描述子。(其实就好比把一个梯度方向为45度的点和一个梯度方向为80度方向的点对齐,进而在判断其他参数是否相似,如果相似,则认为是同一个特征点,当然在整个对齐的过程中就做到了旋转不变)

后续:
前几天刚好自己编程实现了一下SIFT,在实现SIFT的同时找了很多很多的资料。前面这些有一点简单的翻译成分在,不过大多数还是我在看资料以及coding时个人的一些理解,虽然大致是了解了SIFT的整个过程,但是coding却是更多的注重细节。比如插值,比如高斯核的建立等等。另外也概叹要想做好创新,突破,必须要有很宽广的知识面。比如SIFT中可以看到很多方法都是前人所做过的,角点中Hessian矩阵的应用,Gassian多尺度的滤波。怎样将这些方法结合起来,建立一个well-performance 框架才是真正的难题。

 
参考文献:
[1] David.G.Lowe.2004. Distinctive Image Features from Scale-Invariant Keypoints.
[2] Koenderink,J.J.1984. The structure of images. Biological Cybernetics, 50: 363-396.
[3] Lindeberg,T. 1993. Detecting salient blob-likeimage structure sand their scales with a scale-space primal sketch: a method for focus-of-attention. International Journal of Computer Vision, 11(3):283-318 
[4] Lindeberg,T. 1994. Scale-space theory: A basic tool for analysing structures atdifferent scales. Journal of Applied Statistics, 21(2):224-270.

coding 参考:
[1]http://www.aishack.in/2010/05/sift-scale-invariant-feature-transform
[2]http://blog.csdn.net/v_july_v/article/details/6245939
[3]http://blogs.oregonstate.edu/hess/code/sift/

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。