1. 程式人生 > >特徵提取與檢測(二) --- SIFT演算法

特徵提取與檢測(二) --- SIFT演算法

        SIFT(Scale-invariant feature transform)是一種檢測區域性特徵的演算法,該演算法通過求一幅圖中的特徵點(interest points,or corner points)及其有關scale 和 orientation 的描述子得到特徵並進行影象特徵點匹配,獲得了良好效果,詳細解析如下:

一、SIFT演算法綜述

特點:

1. SIFT特徵是影象的區域性特徵,其對旋轉、尺度縮放、亮度變化保持不變性,對視角變化、仿射變換、噪聲也保持一定程度的穩定性;

2. 獨特性(Distinctiveness)好,資訊量豐富,適用於在海量特徵資料庫中進行快速、準確的匹配;

3. 多量性,即使少數的幾個物體也可以產生大量的SIFT特徵向量;

4. 高速性,經優化的SIFT匹配演算法甚至可以達到實時的要求;

5. 可擴充套件性,可以很方便的與其他形式的特徵向量進行聯合。


應用場景:

目標的自身狀態、場景所處的環境和成像器材的成像特性等因素影響影象配準/目標識別跟蹤的效能。而SIFT演算法在一定程度上可解決:

1. 目標的旋轉、縮放、平移(RST)

2. 影象仿射/投影變換(視點viewpoint)

3. 光照影響(illumination)

4. 目標遮擋(occlusion)

5. 雜物場景(clutter)

6. 噪聲
 

二、SIFT演算法實現步驟

2.1 構建尺度空間

      要實現影象匹配,我們想在構成影象的所有點中通過某種方法選取出一些具有代表性的點,重要的是這些特殊點在影象經過伸縮、旋轉、疊加噪聲和其他一些變化後仍能被提取出來——即具有不變性,這樣我們就可以利用這些具有不變性的特殊點來進行影象的匹配。Lowe提出了一種尋找特殊點的方法,用這種方法找到的點對於影象的尺度變化具有不變性。

       最早的影象匹配使用的是角點檢測(corner detector)。應該說,影象中物體的邊緣是一個比較好的特徵。比較常用的邊緣檢測方法有一階導數邊緣檢測、二階導數邊緣檢測。拉普拉斯邊緣檢測就屬於二階導數邊緣檢測。拉普拉斯運算元為

∇^2=∂^2/(∂x^2 )+∂^2/(∂y^2 )

      Marr和Hildrith提出了高斯拉普拉斯邊緣檢測運算元(LOG運算元,表示為∇^2 G ),在拉普拉斯操作之前先進行高斯平滑操作,以抑制高頻噪聲。高斯函式表示為G(x,y,σ),與原始影象做卷積後,相當於對影象進行了低通濾波,且σ越大,則濾波器截止頻率越低,影象也因失去更多的高頻資訊而更模糊。Lindeberg又提出將上述結果乘以係數σ^2後可獲得尺度不變性,即尺度歸一化的高斯拉普拉斯運算元σ^2 ∇^2 G。     

     首先是用高斯差分(DOG)來近似σ^2 ∇^2 G。Lowe說可以參考熱擴散方程得到,這個公式應該比較關鍵,但我尚不清楚為何

∂G/∂σ=σ∇^2 G

 

     左邊的高斯偏導數可以用差分來近似:

σ∇^2 G=∂G/∂σ≈(G(x,y,kσ)-G(x,y,σ))/(kσ-σ)

      其中k趨近於1就可以取等號了。所以:

G(x,y,kσ)-G(x,y,σ)≈(k-1) σ^2 ∇^2 G

       從中可以看出,高斯差分與尺度歸一化的高斯拉普拉斯運算元σ^2 ∇^2 G僅相差一個比例因子(k-1)。如果我們取k為定值,則在高斯差分中找到的極值點位置大致相當於在σ^2 ∇^2 G中的位置。

 

       高斯金字塔有多組,每組又有多層。一組中的多個層之間的尺度是不一樣的(也就是使用的高斯引數σσ是不同的),相鄰兩層之間的尺度相差一個比例因子k。如果每組有S層,則k=a^{1/S}。上一組影象的最底層影象是由下一組中尺度為2σ的影象進行因子為2的降取樣得到的(高斯金字塔先從底層建立)。高斯金字塔構建完成後,將相鄰的高斯金字塔相減就得到了DoG金字塔。
高斯金字塔的組數一般是:
                                                                             o=\left [ log_{2}min(m,n)) \right ]-a


      o表示高斯金字塔的層數,m,n分別是影象的行和列。減去的係數a可以在0−log_{2}min(m,n))之間的任意值,和具體需要的金字塔的頂層影象的大小有關。
      高斯模糊引數σ(尺度空間),可由下面關係式得到:

                                                \sigma (o,s)=2^{i-1}(\sigma ,k\sigma ,k^{2}\sigma ...k^{n-1}\sigma ) k=2^{1/S}


      其中i為所在的組,S為所在的組的層數。

     下一個減少計算量的方法是分組(Octave),即通過縮小圖片尺寸來減少卷積計算。

 

                                                                                           圖1:分組高斯差分

 2.2 DOG極值點檢測  

       關鍵點是由DOG空間的區域性極值點組成的,關鍵點的初步探查是通過同一組內各DoG相鄰兩層影象之間比較完成的。為了尋找DoG函式的極值點,每一個畫素點要和它所有的相鄰共26個點比較,看其是否比它的影象域和尺度域的相鄰點大或者小。 如果令σ^2 ∇^2 G中的σ不斷變大(為了計算機實現,只能取離散的σ值,對應於圖1的Scale),就可以得到很多輸出影象,這樣區域性極值點的尋找就擴充套件至三維空間(x,y,σ)。正如圖2所示,每個畫素點X需要與上下及周圍共26個鄰近點O比較來確定區域性最大最小極值。

極值點檢測

                                                                                      圖2:極值點檢測

 

                                                                        圖3 不同尺度不同層級檢測示意圖


       假設s=3,也就是每個塔裡有3層,則k=2^{1/S}=2^{1/3},那麼按照上圖可得Gauss Space和DoG space 分別有3個(s)和2個(s-1)分量,在DoG space中,1st-octave兩項分別是σ,kσ; 2nd-octave兩項分別是2σ,2kσ;由於無法比較極值,我們必須在高斯空間繼續新增高斯模糊項,使得形成σ,kσ,k^{2}σ,k^{3}σ,k^{4}σ這樣就可以選擇DoG space中的中間三項kσ,k^{2}σ,k^{3}σ(只有左右都有才能有極值),那麼下一octave中(由上一層降取樣獲得)所得三項即為2kσ,2k^{2}σ,2k^{3}σ,其首項2kσ=2^{4/3}。剛好與上一octave末項k^{3}σ=2^{3/3}尺度變化連續起來,所以每次要在Gaussian space新增3項,每組(塔)共S+3層影象,相應的DoG金字塔有S+2層影象。

2.3 關鍵點定位

       離散空間的極值點並不是真正的極值點,圖4顯示了二維函式離散空間得到的極值點與連續空間極值點的差別。利用已知的離散空間點插值得到的連續空間極值點的方法叫做子畫素插值(Sub-pixel Interpolation)。

                                                                           圖4 離散空間與連續空間的極值點差異 

      為了提高關鍵點的穩定性,需要對尺度空間DoG函式進行曲線擬合。利用DoG函式在尺度空間的Taylor展開式(擬合函式)為:

       其中,求導並讓方程等於零,可以得到極值點的偏移量為:

      對應極值點,方程的值為:

      其中,代表相對插值中心的偏移量,當它在任一維度上的偏移量大於0.5時(即x或y或),意味著插值中心已經偏移到它的鄰近點上,所以必須改變當前關鍵點的位置。同時在新的位置上反覆插值直到收斂;也有可能超出所設定的迭代次數或者超出影象邊界的範圍,此時這樣的點應該刪除,在Lowe中進行了5次迭代。另外,過小的點易受噪聲的干擾而變得不穩定,所以將小於某個經驗值(Lowe論文中使用0.03,Rob Hess等人實現時使用0.04/S)的極值點刪除。同時,在此過程中獲取特徵點的精確位置(原位置加上擬合的偏移量)以及尺度。


2.4 消除邊緣影響

       一個定義不好的高斯差分運算元的極值在橫跨邊緣的地方有較大的主曲率,而在垂直邊緣的方向有較小的主曲率。

DOG運算元會產生較強的邊緣響應,需要剔除不穩定的邊緣響應點。獲取特徵點處的Hessian矩陣,主曲率通過一個2x2 的Hessian矩陣H求出:

  

      H的特徵值α和β代表x和y方向的梯度,

表示矩陣H對角線元素之和,表示矩陣H的行列式。假設是α較大的特徵值,而是β較小的特徵值,令,則

      

       D的主曲率和H的特徵值成正比,令為α最大特徵值,β為最小的特徵值,則公式的值在兩個特徵值相等時最小,隨著的增大而增大。值越大,說明兩個特徵值的比值越大,即在某一個方向的梯度值越大,而在另一個方向的梯度值越小,而邊緣恰恰就是這種情況。所以為了剔除邊緣響應點,需要讓該比值小於一定的閾值,因此,為了檢測主曲率是否在某域值r下,只需檢測如下:

      上式成立時將關鍵點保留,反之剔除。

2.5 尋找關鍵點的主方向

       經過上面的步驟已經找到了在不同尺度下都存在的特徵點,為了實現影象旋轉不變性,需要給特徵點的方向進行賦值。利用特徵點鄰域畫素的梯度分佈特性來確定其方向引數,再利用影象的梯度直方圖求取關鍵點區域性結構的穩定方向找到了特徵點,也就可以得到該特徵點的尺度σ,也就可以得到特徵點所在的尺度影象:


     計算以特徵點為中心、以3×1.5σ為半徑的區域影象的幅角和幅值,每個點L(x,y)的梯度的模m(x,y)以及方向θ(x,y)可通過下面公司求得:


       計算得到梯度方向後,就要使用直方圖統計特徵點鄰域內畫素對應的梯度方向和幅值。梯度方向的直方圖的橫軸是梯度方向的角度(梯度方向的範圍是0到360度,直方圖每36度一個柱共10個柱,或者沒45度一個柱共8個柱),縱軸是梯度方向對應梯度幅值的累加,在直方圖的峰值就是特徵點的主方向。在Lowe的論文還提到了使用高斯函式對直方圖進行平滑以增強特徵點近的鄰域點對關鍵點方向的作用,並減少突變的影響。為了得到更精確的方向,通常還可以對離散的梯度直方圖進行插值擬合。具體而言,關鍵點的方向可以由和主峰值最近的三個柱值通過拋物線插值得到。在梯度直方圖中,當存在一個相當於主峰值80%能量的柱值時,則可以將這個方向認為是該特徵點輔助方向。所以,一個特徵點可能檢測到多個方向(也可以理解為,一個特徵點可能產生多個座標、尺度相同,但是方向不同的特徵點)。Lowe在論文中指出

15%的關鍵點具有多方向,而且這些點對匹配的穩定性很關鍵。

       得到特徵點的主方向後,對於每個特徵點可以得到三個資訊(x,y,σ,θ)(x,y,σ,θ),即位置、尺度和方向。由此可以確定一個SIFT特徵區域,一個SIFT特徵區域由三個值表示,中心表示特徵點位置,半徑表示關鍵點的尺度,箭頭表示主方向。具有多個方向的關鍵點可以被複製成多份,然後將方向值分別賦給複製後的特徵點,一個特徵點就產生了多個座標、尺度相等,但是方向不同的特徵點。

2.6 生成特徵描述

       通過以上的步驟已經找到了SIFT特徵點位置、尺度和方向資訊,下面就需要使用一組向量來描述關鍵點也就是生成特徵點描述子,這個描述符不只包含特徵點,也含有特徵點周圍對其有貢獻的畫素點。描述子應具有較高的獨立性,以保證匹配率
特徵描述符的生成大致有三個步驟:

  1. 校正旋轉主方向,確保旋轉不變性。
  2. 生成描述子,最終形成一個128維的特徵向量
  3. 歸一化處理,將特徵向量長度進行歸一化處理,進一步去除光照的影響。

       為了保證特徵向量的旋轉不變性,要以特徵點為中心,在附近鄰域內將座標軸旋轉θ(特徵點的主方向)角度,即將座標軸旋轉為特徵點的主方向。旋轉後鄰域內畫素的新座標為:

 

       旋轉後以主方向為中心取 8×8的視窗。下圖所示,左圖的中央為當前關鍵點的位置,每個小格代表為關鍵點鄰域所在尺度空間的一個畫素,求取每個畫素的梯度幅值與梯度方向,箭頭方向代表該畫素的梯度方向,長度代表梯度幅值,然後利用高斯視窗對其進行加權運算。最後在每個4×4的小塊上繪製8個方向的梯度直方圖,計算每個梯度方向的累加值,即可形成一個種子點,如右圖所示。每個特徵點由4個種子點組成,每個種子點有8個方向的向量資訊。這種鄰域方向性資訊聯合增強了演算法的抗噪聲能力,同時對於含有定位誤差的特徵匹配也提供了比較理性的容錯性。 

       與求主方向不同,此時每個種子區域的梯度直方圖在0-360之間劃分為8個方向區間,每個區間為45度,即每個種子點有8個方向的梯度強度資訊。在實際的計算過程中,為了增強匹配的穩健性,Lowe建議對每個關鍵點使用4×44×4共16個種子點來描述,這樣一個關鍵點就可以產生128維的SIFT特徵向量

       通過對特徵點周圍的畫素進行分塊,計算塊內梯度直方圖,生成具有獨特性的向量,這個向量是該區域影象資訊的一種抽象,具有唯一性。

 

參考文獻

1、sift演算法詳解及應用(課件)。(本文件簡明扼要的簡述了SIFT演算法和影象匹配以及匹配修正。圖文並茂,一覽全貌)

      http://wenku.baidu.com/view/87270d2c2af90242a895e52e.html?re=view

2、SIFT演算法詳解(sift操作過程理論通俗,尤其是高階泰勒展開式及高階導數分析的很好,對理解亞畫素定位擬閤中的影象具體程式設計操作很有用)

http://blog.csdn.net/zddblog/article/details/7521424

3、SIFT特徵分析與原始碼解讀(1模擬金字塔的過程解釋的很詳細,帶有動畫模擬;2 在尋找特徵點進行亞畫素定位擬閤中的影象很形象)

   http://blog.csdn.net/xw20084898/article/details/16832755

4、【OpenCV】SIFT原理與原始碼分析:關鍵點描述(對關鍵點描述子區域的取捨講解的很詳細)

   http://blog.csdn.net/xiaowei_cqu/article/details/8113565

5、【OpenCV】SIFT原理與原始碼分析(對sift 演算法採用分部分敘述且帶有原始碼分析說明)

   http://blog.csdn.net/xiaowei_cqu/article/details/8069548

6、opencv2.4.9sift原始碼分析(1趙春江的這篇文章是我目前看到分析sift演算法比較全面的;2尤其給出了使用三維直方圖來分析三線性插值,對理解描述子的生成作用很大;3 給出了原始碼分析和演示結果)

http://wenku.baidu.com/view/d7edd2464b73f242336c5ffa.html

 http://download.csdn.net/detail/zhaocj/8294793

7、九之再續:教你一步一步用c語言實現sift演算法、下

(1演算法中尋找主方向使用的拋物線插值擬合方法;2 描述子三次插值)

   http://blog.csdn.net/v_JULY_v/article/details/6246213

8、RobHess的SIFT原始碼分析:綜述(各個子程式詳解及分析很細緻,一概全貌)

   http://blog.csdn.net/masibuaa/article/details/9191309

9、特徵點檢測學習_1(sift演算法)(1這篇文章沒有太多理論分析,但結合QT和OpenCV做出了生動的sift演算法匹配演示,有圖很直觀生動呀,用程式配圖一目瞭然;2 簡述對robhess 的c版本sift程式碼在c++中的使用注意問題 )

    http://www.cnblogs.com/tornadomeet/archive/2012/08/16/2643168.html

 10、OpenCV 中c版本sift原始碼網址

 http://blogs.oregonstate.edu/hess/code/sift/ 

11、【特徵匹配】SIFT原理與C原始碼剖析(這個也不錯,圖文並茂,還帶有  原始碼分析,總體來說是以程式帶動問題分析)

  http://blog.csdn.net/luoshixian099/article/details/47377611

12、插值與擬合(對多項式及其插值講解還不錯)

http://wenku.baidu.com/link?url=wWcqLrpokQrjZZKzFbuJ4QDbZXZkMByCu-KaVKrSyGD6fh9Bpk1kZOPitpkFpNBw_no8UoyWY2DGQg9I7aL_tO3oi7z5mUK7cN8Sca6dX-O

13、線性插值與拋物線插值(對這兩種插值講解的很詳細,是目前發現最 好的一版

       http://www.docin.com/p-711275966.html

14、奇異值分解(對奇異值怎麼來的講解比較細緻)

       http://blog.sina.com.cn/s/blog_53eb0fdf0101sfu1.html

15,SIFT特徵點提取  (重點參考)