計算機視覺-sift(1)原理

1999年由David Lowe首先發表於計算機視覺國際會議(International Conference on Computer Vision,ICCV),2004年再次經David Lowe整理完善後發表於International journal of computer vision(IJCV。截止2014年8月,該論文單篇被引次數達25000餘次。---來自百科

本打算對04年的論文進行翻譯,結果。居然搜到完整翻譯版,雖然翻譯的不太好,不過有聊勝於無。本文的講解大部分主要還是借鑑了最下面參考文獻【8】的資料,先謝過作者,該作者對opencv的好多源碼進行了分析,很強啊。

先說sift中一步一步的的動機(motivation):對於普通的圖像匹配來說(都是平面物體:比如放在這個桌子上的書,然後這本書放在另一個地方,而非人臉在不斷的旋轉,一下只能看到側臉,一下看到前臉。即sift的優點之處,旋轉,縮放,尺度不變的特性,而這裏都指的是平面內,而不是平面外的旋轉)【此觀點如果有誤還望告知】,sift的先驅們發現,對於平面物體來說只要對兩幅圖像找到超過3對物體間的匹配點,就能使用射影幾何進行對應。而對於旋轉的,縮放的圖像,如何建立穩定的關鍵點,就是關鍵了,當然必須考慮到光照變化,所以相對來說,比如角點、邊緣、亮區域中的暗點,暗區域中的亮點等等。--這就是關鍵點檢測。ps:sift是建立在灰度圖上的。

當然找關鍵點的方法就是求取空間的極值,可是對於只有離散值的圖像來說,如何能夠模擬連續值形式的函數來找到最小值,這是問題的關鍵。而且通常來說,要求圖像的最值,需要求導什麼的,而這都是使用濾波器的方法來實現的。可是對於不同尺度的圖像或者其中的物體來說,同一個尺寸的濾波器濾波之後得到的極值有可能差別較大,所以就出現了金字塔形狀。【此觀點如果有誤,還望告知】假設圖像是深層的,那麼不斷的不同大小的尺度的圖中是會有相同信息的,所以這可以看成是插值形式,即當前圖像與圖像濃縮成一個點之間無限的插值而成的不同尺度卻內容相同的圖像序列。可想而知這時候關鍵點是有了,可是雜質太多,所以需要提純,所以在極值之後得到關鍵點,接着就需要基於關鍵點進行篩選,得到更穩定的關鍵點。---這就是關鍵點定位。ps:解決了縮放、尺度的特性問題。

然後爲了使得關鍵點更加穩固,如果加上關鍵點周邊的信息,一起作爲其特徵,那麼就能更好的建立特徵空間。這時候可以引入方向信息,即求其梯度,這樣只要將不同圖片的這一步的方向都旋轉到同一個方向,那麼就能夠更好的匹配配了,這樣就解決了旋轉的問題。---這就是方向確定。ps:這樣尺度、方向,位置信息就都有了。

接下來就是將上面的這些信息都進行統一的描述,從而建立最後的sift特徵。---這就是建立描述符。

一、原理分析

1、尺度空間極值點檢測

     尺度空間:高大上的詞,具體可參考[6,7]。其實就是對應着平時拍照時候,攝像頭的聚焦過程產生的清晰還是模糊的意思。爲了更直觀,先從維基上找到的資料來解釋下什麼是尺度空間,當然這裏指的是計算機視覺中的尺度空間。對於一幅給定的圖像 f(x, y), 它的線性(高斯)尺度空間就是由該圖像與一個2維高斯核卷積得到的 L(x, y; t) .其中卷積核如下:

g(x, y; t) = \frac {1}{2 \pi t}e^{-(x^2+y^2)/2t}\,                                   (公式1)

其中爲模糊半徑的平方。得到的尺度空間爲:

L(\cdot, \cdot ; t)\ = g(\cdot, \cdot ; t) * f(\cdot, \cdot) ,                                    (公式2)

 L 中的點表示只在變量 x, y,上執行卷積操作, t 就是尺度參數了,是用來表示當前在哪個尺度級別上進行卷積。這個定義 L 中限制了 t  \geq 0,不過可以看得出來,計算機視覺中得到的都是離散的,間斷的圖像序列,而沒法得到連續的圖像。當然尺度參數即爲高斯過濾器的方差 t = \sigma^2 ,如果說t = 0 那麼過濾器 g 就變成一個脈衝函數,導致的結果就是 L(x, y; 0) = f(x, y), 也就是在 t = 0 這個級別的尺度空間,其實就是圖像 f 自己。隨着t 的變大,L 就是針對圖像上使用越來越大的平滑過濾器,因而會移除越來越多圖像內容的細節。因爲過濾器的標準差是 \sigma = \sqrt{t},所以很大程度上明顯小於該值的一些細節就會被忽略掉:

說完了尺度空間,現在接着說sift的第一步,極值點檢測。ps:尺度是自然存在的,不是人爲創造的,高斯卷積只是表現尺度的一種形式。

     高斯卷積(也叫做高斯平滑,高斯模糊):通常可以用來減少圖像噪聲以及降低細節層次。因爲在實際應用中,在計算高斯函數的離散近似時,在大概3σ距離之外的像素都可以看作不起作用,這些像素的計算也就可以忽略。通常,圖像處理程序只需要計算的矩陣就可以保證相關像素影響。所以我們先計算σ的值,然後通過該值計算出所需要的模板的大小,然後對模板進行歸一化,接着用其對圖像進行高斯過濾。比如當方差爲0.6時得到的就是5×5的高斯模板,可以通過matlab代碼生成:

a=fspecial('gaussian',5,0.6)

    

       ps:高斯模糊具有園對稱性;而且是線性可分的,所以可以在二維的圖像上對每一維單獨進行一維高斯模糊來減少計算量,這可以參考【4】中的2.3分離高斯模糊部分;而且對於一幅圖像進行多次連續高斯模糊的效果與一次更大的高斯模糊可以產生同樣的效果,大的高斯模糊的半徑是所用多個高斯模糊半徑平方和的平方根,比如,使用半徑分別爲6 和8的兩次高斯模糊變換得到的效果等於一次半徑爲10的高斯模糊效果,因爲6^2+8^2=10^2。所以使用多個連續較小的高斯模糊處理不會比單個高斯較大處理時間少。

上面介紹了尺度空間和高斯模糊,接下來就是介紹高斯金字塔了,通過構建多層的高斯金字塔來計算後續的圖片中的極值。

 高斯金字塔


圖1,高斯金字塔

高斯金字塔共分O 組(Octave),每組又分S 層(Layer)。組內各層圖像的分辨率是相同的,即長和寬相同,但尺度逐漸增加,即越往塔頂圖像越模糊。而下一組的圖像是由上一組圖像(上一組倒數第3張,即上圖中的2組的第0層是第一組的上往下數第3張採樣得到的)按照隔點降採樣得到的,即圖像的長和寬分別減半。高斯金字塔的組數O 是由輸入圖像的分辨率得到的,因爲要進行隔點降採樣,所以在執行降採樣生成高斯金字塔時,一直到4*4大小(因爲太小的圖片也沒什麼意義了)。其中組數公式爲:

                                                                                                (公式3)

其中,X 和Y 分別爲輸入圖像的長和寬,⌊ ⌋表示向下取整。並且每組的金字塔的層數S 爲:S = s + 2+1 。這裏Lowe 建議s 爲3 。(s爲建議的,2是爲了不同組之間能夠平滑過渡而在頂部加上的2層,1爲最底的原始層)【8】假設當前圖像大小爲512*512,則如下操作:


上面公式中減2 是因爲假設當前圖像即爲輸入圖像,而有的資料減3 是因爲,他們把自然界作爲第0組,而經過相機拍攝就成了第1組,所以是多減一次(當然了,到底減多少,任君喜歡,這不是重點)。這時候就需要依據當前圖像建立自然場景的第 0 組圖像了,即用當前圖像進行插值得到例如上面那樣的1024*1024的一張圖片。

          得到了組數之後,就是計算組內尺度和組間尺度了。記得這裏是假設當前得到的圖片的尺度爲0.5的,即第1組的第0層(自然界爲第0組),即拍照拍到之後拿到的那張圖片。我們可以很自然的知道,這是有組內尺度和組間尺度的。對於組內相鄰的兩幅圖片來說:

                                                                                                 (公式4)

假設,這裏的s爲小寫的,不是表示層數的那個大S。(爲什麼使用1/2,這個可以看lowe的論文【1】)所以,對於某一組來說,當s =3時,有S=s+2+1 =6幅圖片,即[0,1,2,3,4,5):


而對於組間相鄰的尺度來說,因爲後一組是通過前一組的倒數第3幅圖進行降採樣得到的,即前一組的第s幅。爲,將帶入得其爲,即後一組的第0幅圖爲前一組第0幅圖的2倍尺度。同時推出相鄰兩組同一層的圖像都是2倍尺度關係的。則,總的尺度座標爲:

                                               (公式5)

其中,o 表示第幾組,r表示組內第幾層。

        在lowe的論文中,他將第0層,也就是自然界層的初始尺度定義爲1.6,而我們獲取的圖片初始尺度爲0.5,則圖像金字塔第0層的實際尺度爲sqrt(1.6*1.6-0.5*0.5)=1.52(之所以可以這麼計算就是因爲上面高斯金字塔之上的ps部分所述)。當然這是爲了避免檢測極值點之前就對原始圖像的高斯平滑以致於圖像丟失高頻信息,所以才建議在建立尺度空間前首先對原始圖像的長寬擴展一倍,以保留原始圖像的信息,也就是我們之前說的那個假設你獲得了圖像是512*512的,那麼就弄一個1024*1024的作爲最底層圖 ,這時候因爲圖像擴展造成的尺度計算爲(即通過計算機得到的真實尺度),當然這一組在很多資料中也叫做第 -1 組:

                                                                                      (公式6)

      本來對於關鍵點的檢測,可以 利用LoG(高斯拉普拉斯方法,Laplacian of Gaussian),即圖像的二階導數,能夠在不同的尺度下檢測到圖像的斑點特徵,從而可以確定圖像的特徵點。lindeberg在文獻《scale space theory:a basic tool for analysising structures at different scales》中指出尺度規範化的log算子具有真正的尺度不變性。但LoG 的效率不高。所以sift不這麼做,作者對兩個相鄰高斯尺度空間的圖像相減,得到一個DoG(高斯差分,Difference of Gaussians)的響應值圖像D(x, y, σ)來近似LoG :

                              (公式7)

兩者爲什麼能夠等效,仔細的推導可以看這裏的3.4 高斯差分金字塔部分。用DoG 代替LoG 並不影響對圖像斑點位置的檢測。而且用DoG 近似LoG 可以實現下列好處:第一是LoG 需要使用兩個方向的高斯二階微分卷積核,而DoG 直接使用高斯卷積核,省去了卷積核生成的運算量;第二是DoG 保留了個高斯尺度空間的圖像,因此在生成某一空間尺度的特徵時,可以直接使用公式2產生的尺度空間圖像,而無需重新再次生成該尺度的圖像;第三是DoG 具有與LoG 相同的性質,即穩定性好、抗干擾能力強。爲了在連續的尺度下檢測圖像的特徵點,需要建立DoG 金字塔,而DoG 金字塔的建立又離不開高斯金字塔的建立,如下圖所示,左側爲高斯金字塔,右側爲DoG 金字塔【8】: 


圖2 高斯金字塔的部分圖,及差分金字塔

高斯金字塔的組內相鄰兩層相減,而兩組間的各層是不能相減的。因此高斯金字塔每組有s+3 層圖像,而DoG 金字塔每組則有s+2 層圖像 。我們可以發現未被利用到的高斯金字塔的第0組的第0層和最上面一組的最上面一層;而dog金字塔的每組的第0層和頂層未被用到(原因如下)。

        極值點的搜索是在DoG 金字塔內進行的,這些極值點就是候選的特徵點。在搜索之前,我們需要在DoG 金字塔內剔除那些像素值過小的點,因爲這些像素具有較低的對比度,它們肯定不是穩定的特徵點。極值點的搜索不僅需要在它所在尺度空間圖像的鄰域內進行,還需要在它的相鄰尺度空間圖像內進行,如圖2 所示。每個像素在它的尺度圖像中一共有8 個相鄰點,而在它的下一個相鄰尺度圖像和上一個相鄰尺度圖像還各有9 個相鄰點(圖2 中綠色標註的像素),也就是說,該點是在3×3×3的立方體內被包圍着,因此該點在DoG 金字塔內一共有26 個相鄰點需要比較,來判斷其是否爲極大值或極小值。這裏所說的相鄰尺度圖像指的是在同一個組內,因此在DoG 金字塔內,每一個組的第0 層和最後一層各只有一個相鄰尺度圖像,所以在搜索極值點時無需在這兩層尺度圖像內進行,從而使極值點的搜索就只在每組的中間s 層尺度圖像內進行 【8】。搜索的過程是這樣的:從每組的第1 層開始,以第1 層爲當前層,對第1 層的DoG 圖像中的每個點取一個3×3×3 的立方體,立方體上下層分別爲第0 層和第2 層。這樣,搜索得到的極值點既有位置座標(該點所在圖像的空間座標),又有尺度空間座標(該點所在層的尺度)。當第1 層搜索完成後,再以第2 層爲當前層,其過程與第1 層的搜索類似,以此類推。:


2、關鍵點的定位

       從上面的搜索中就能夠得到許多的極值點了,之所謂極值點,就是都是一羣待選的點,不是直接就可以用的關鍵點。因爲它們還存在一些不確定的因素,首先是極值點的搜索是在離散空間內進行的,並且這些離散空間還是經過不斷的降採樣得到的。如果把採樣點擬合成曲面後我們會發現,原先的極值點並不是真正的極值點,也就是離散空間的極值點並不是連續空間的極值點,如下圖【4】:


圖3

(接下來這一大段都是來自參考文獻【8】,因爲覺得該作者講的詳細,所以直接複製過來這部分了)爲了提高關鍵點的穩定性,需要對尺度空間DoG函數進行曲線擬合。因爲,極值點是一個三維矢量,即它包括極值點所在的圖像座標,及尺度座標:。利用DoG函數在尺度空間的Taylor展開式(擬合函數),假設我們在點處展開,展開2階即可 

                         (公式8)

對應的矩陣形式爲:

       

                               (公式9)

在這裏 表示離散空間下的插值中心(在離散空間內也就是採樣點)座標, 表示擬合後連續空間下的插值點座標,設,則表示相對於插值中心,插值後的偏移量。因此上述公式可寫成:

                                                                                  (公式10)

 求導得:

                                                                (公式11)

將其置爲0,得到結果爲:

                                                                                                    (公式12)

將上面的極值點帶入求導前的原公式(10)得:

                                    (公式13)

對於公式12 所求得的偏移量如果大於0.5(只要x、y 和σ 任意一個量大於0.5),則表明插值點已偏移到了它的臨近的插值中心,所以必須改變當前的位置,使其爲它所偏移到的 插值中心處,然後在新的位置上重新進行泰勒級數插值擬合,直到偏移量小於0.5 爲止(x、y 和σ 都小於0.5),這是一個迭代的工程。當然,爲了避免無限次的迭代,我們還需要設置一個最大迭代次數,在達到了迭代次數但仍然沒有滿足偏移量小於0.5 的情況下,該極值點就要被剔除掉。另外,如果由公式13 所得到的極值過小,即時(假設圖像的灰度值在0~1.0 之間),則這樣的點易受到噪聲的干擾而變得不穩定,所以這些點也應該剔除。而在opencv 中,使用的是下列公式來判斷其是否爲不穩定的極值 :

                                                                                                                (公式14)

其中T 爲經驗閾值,系統默認初始化爲0.04。

        僅僅去除低對比度的極值點對於特徵的穩定性還是遠遠不夠的。DoG函數在圖像邊緣也有着較強的邊緣響應,因此我們還需要排除邊緣響應。一旦特徵點落在圖像的邊緣上,這些點就是不穩定的點。這是因爲一方面圖像邊緣上的點是很難定位的,具有定位的歧義性;另一方面這樣的點很容易受到噪聲的干擾而變得不穩定。因此我們一定要把這些點找到並剔除掉。它的方法與Harris 角點檢測算法相似,即一個平坦的DoG 響應峯值往往在橫跨邊緣的地方有較大的主曲率,而在垂直邊緣的方向上有較小的主曲率,主曲率可以通過2×2 的Hessian 矩陣H 求出 :

                                                                                 (公式15)

其中分別表示對DoG 圖像中的像素在x 軸方向和y 軸方向上求二階偏導和二階混合偏導。(而這4個值,可以用有限差分求導來近似得到)在這裏,我們不需要求具體的矩陣H 的兩個特徵值α 和β,而只要知道兩個特徵值的比例就可以知道該像素點的主曲率 。矩陣H 的直跡和行列式分別爲:

                                                                                           (公式16)

                                                                                     (公式17)

我們首先剔除掉那些行列式爲負數的點,即Det(H) < 0,因爲如果像素的曲率有不同的符號,則該點肯定不是特徵點。設α > β,並且α = γ β,其中γ > 1,則 :

                                                             (公式18)

上式的結果只與兩個特徵值的比例有關,而與具體的特徵值無關。我們知道,當某個像素的H 矩陣的兩個特徵值相差越大,即γ 很大,則該像素越有可能是邊緣。對於上面那個公式來說,當兩個特徵值相等時,等式的值最小,隨着γ 的增加,等式的值也增加。所以,要想檢查主曲率的比值是否小於某一閾值γ,只要檢查下式是否成立即可 :

                                                                                             (公式19)

對於不滿足上式的極值點就不是特徵點,因此應該把它們剔除掉。Lowe 給出γ 爲10。在上面的運算中,需要用到有限差分法求偏導 。這部分可以看看這裏的4.3有限差分求導

3、方向角度的確定

        上面這樣就算是從DoG圖中找到極值點,然後篩選下留下的就是關鍵點了。這時候爲了解決旋轉不變性,並且使得關鍵點更加的魯棒,就對其周圍進行深挖,將周邊的信息賦予到這個關鍵點上。就是需要根據檢測到的特徵點所在的高斯尺度圖像的局部結構求得一個方向基準。該高斯尺度圖像的尺度σ 是已知的,並且該尺度是相對於高斯金字塔所在組的基準層的尺度,即

               (公式20,該式子的r 表示的是第幾層,而下面的r 表示的是半徑)

而所謂局部結構指的是在高斯尺度圖像中以特徵點爲中心,以r 爲半徑的區域內計算所有像素梯度的幅角和幅值,半徑r 爲: 

                                                                                                                                 (公式21)

其中σ 就是上面提到的相對於所在組的基準層的高斯尺度圖像的尺度。當然了像素梯度的幅值和幅角的計算公式計算公式爲:

                                     (公式22)

                                                                 (公式23)

因爲在以r 爲半徑的區域內的像素梯度幅值對圓心處的特徵點的貢獻是不同的,因此還需要對幅值進行加權處理,這裏採用的是高斯加權,該高斯函數的方差 爲:

                                                                                                                    (公式24)

 在完成特徵點鄰域範圍內的梯度計算後,還要應用梯度方向直方圖來統計鄰域內像素的梯度方向所對應的幅值大小。具體的做法是,把360度分爲36 個柱,則每10度爲一個柱,其中0-9爲第1 柱,10-19爲第2 柱,以此類推。在以r 爲半徑的區域內,把那些梯度方向在0-9範圍內的像素找出來,把它們的加權後的梯度幅值相加在一起,作爲第1 柱的柱高;求第2 柱以及其他柱的高度的方法相同。爲了防止某個梯度方向角度因受到噪聲的干擾而突變,我們還需要對梯度方向直方圖進行平滑處理 。Opencv中直方圖以周圍360度爲範圍,每10度爲一個柱,一共36個柱,柱所代表的方向爲像素點梯度方向,柱的長短代表了梯度幅值。根據Lowe的建議,模板採用[0.25,0.5,0.25],並連續加權兩次: 

                (公式25)

(這裏要注意下,不同版本的opencv中實現的方法不一樣)

其中h 和H 分別表示平滑前和平滑後的直方圖。由於角度是循環的,即0度=360度,如果出現h(j),j 超出了(0,…,15)的範圍,那麼可以通過圓周循環的方法找到它所對應的、在0-360度之間的值,如h(-1) = h(35) 。


圖4

上圖只畫了8個柱。該圖來自這裏。方向直方圖的峯值則代表了該特徵點處鄰域梯度的方向,以直方圖中最大值作爲該關鍵點的主方向。爲了增強匹配的魯棒性,只保留峯值大於主方向峯值80%的方向作爲該關鍵點的輔方向。因此,對於同一梯度值的多個峯值的關鍵點位置,在相同位置和尺度將會有多個關鍵點被創建但方向不同。僅有15%的關鍵點被賦予多個方向,但可以明顯的提高關鍵點匹配的穩定性。實際編程實現中,就是把該關鍵點複製成多份關鍵點,並將方向值分別賦給這些複製後的關鍵點,並且,離散的梯度方向直方圖要進行插值擬合處理,來求得更精確的方向角度值。

        這樣,直方圖的主峯值,即最高的那個柱體所代表的方向就是該特徵點處鄰域範圍內圖像梯度的主方向,也就是該特徵點的主方向。由於柱體所代表的角度只是一個範圍,如第1柱的角度爲0-9度,因此還需要對離散的梯度方向直方圖進行插值擬合處理,以得到更精確的方向角度值。例如我們已經得到了第i 柱所代表的方向爲特徵點的主方向,則擬合公式爲 :

                                               (公式26)

                                                                                          (公式27)

其中,H 爲由公式34 得到的直方圖,角度θ 的單位是度。同樣的,上面兩個公式也存在着之前那個直方圖平滑所遇到的角度問題,處理的方法同樣還是利用角度的圓周循環。 

    每個特徵點除了必須分配一個主方向外,還可能有一個或更多個輔方向,增加輔方向的目的是爲了增強圖像匹配的魯棒性。輔方向的定義是,當存在另一個柱體高度大於主方向柱 體高度的80%時,則該柱體所代表的方向角度就是該特徵點的輔方向。在第2 步中,我們實現了用兩個信息量來表示一個特徵點,即位置和尺度。那麼經過上面的計算,我們對特徵點的表示形式又增加了一個信息量:方向, 即。如果某個特徵點還有一個輔方向,則這個特徵點就要用兩個值來表示:,其中表示主方向,表示輔助方向。而其他的變量:x, y, σ 不變。 

4、描述符的建立

        描述的目的在於之前的那些零碎的關鍵點的計算之後,如何用一組向量來將這個關鍵點描述出來,這個描述子不但包含關鍵點,也包含了周邊貢獻的像素點的信息。因爲已經有了尺度,位置和方向等信息,所以能夠有較好的適應性。思路就是對關鍵點周圍圖像區域分塊,計算塊內梯度直方圖生成具有獨特性的向量,該向量就是該區域圖像信息的一種抽象,具有唯一性。

        在圖像局部區域內,這些參數可以重複的用來描述局部二維座標系統,因爲這些參數具有不變性。下面就來計算局部圖像區域的描述符,描述符既具有可區分性,又具有對某些變量的不變性,如光亮或三維視角。描述符是與關鍵點所在的尺度有關的,所以描述關鍵點是需要在該關鍵點所在的高斯尺度圖像上進行的。在高斯尺度圖像上,以關鍵點爲中心,將其附近鄰域劃分爲d×d 個子區域(Lowe 取d = 4)。每個子區域都是一個正方形,正方形的邊長爲3σ,也就是說正方形的邊長有3σ 個像素點(這裏當然要對3σ 取整)。σ 爲相對於關鍵點所在的高斯金字塔的組的基準層圖像的尺度,即公式20 所表示的尺度。考慮到實際編程的需要,關鍵點鄰域範圍的邊長應爲3σ(d+1),因此關鍵點鄰域區域一共應有3σ(d+1)×3σ(d+1)個像素點。爲了保證關鍵點具有旋轉不變性,還需要以關鍵點爲中心,將上面確定下來的關鍵點鄰域區域旋轉θ(θ 就是該關鍵點的方向)。由於是對正方形進行旋轉,爲了使旋轉後的區域包括整個正方形,應該以從正方形的中心到它的邊的最長距離爲半徑,也就是正方形對角線長度的一半,即: 

                                                                                                             (公式28)

        所以上述的關鍵點鄰域區域實際應該有(2r+1)×(2r+1)個像素點。由於進行了旋轉,則這些採樣點的新座標爲: 

                                                              (公式29)

其中是旋轉後的像素的新座標,是旋轉前的座標。

ps:從《matrix computations.4th》中可以看到:

即上面關鍵點的旋轉是逆時針旋轉θ度:


圖5.上圖中上左一到上右一是座標系順時針的旋轉了,其實也就等同於該座標逆時針的旋轉了。

        這時,我們需要計算旋轉以後關鍵點鄰域範圍內像素的梯度幅值和梯度幅角。這裏的梯度幅值還需要根據其對中心特徵點貢獻的大小進行加權處理,加權函數仍然採用高斯函數,它的方差的平方爲。在實際應用中,我們是先以關鍵點爲圓心,以公式28 中的r 爲半徑,計算該圓內所有像素的梯度幅角和高斯加權後的梯度幅值,然後再根據公式29 得到這些幅值和幅角所對應的像素在旋轉以後新的座標位置。 

       在計算關鍵點描述符的時候,我們不需要精確知道鄰域內所有像素的梯度幅值和幅角,我們只需要根據直方圖知道其統計值即可。這裏的直方圖是三維直方圖 。如下圖 所示:


圖6

       上圖 中的三維直方圖爲一個立方體,立方體的底就是關鍵點鄰域區域。如前面所述,該區域被分爲4×4 個子區域,即16 個子區域,鄰域內的像素根據其座標位置,把它們歸屬於這16 個子區域中的一個。立方體的三維直方圖的高爲鄰域像素幅角的大小。我們把360 度的幅角範圍進行8 等分,每一個等份爲45 度。則再根據鄰域像素梯度幅角的大小,把它們歸屬於這8 等份中的一份。這樣三維直方圖就建立了起來,即以關鍵點爲中心的鄰域像素根據其座標位置,以及它的幅角的大小被劃歸爲某個小正方體(如圖4 中的C 點,在這裏,可以通過歸一化處理,得到邊長都爲單位長度的正方體的)內,該直方圖一共有4×4×8=128個這樣的正方體。而這個三維直方圖的值則是正方體內所有鄰域像素的高斯加權後的梯度幅值之和,所以一共有128 個值。我們把這128 個數寫成一個128 維的矢量,該矢量就是該特徵點的特徵矢量,所有特徵點的矢量構成了最終的輸入圖像的SIFT 描述符。

       顯然,正方體的中心應該代表着該正方體。但落入正方體內的鄰域像素不可能都在中心,因此我們應該對上面提到的梯度幅值做進一步處理,根據它對中心點位置的貢獻大小進行加權處理,即在正方體內,根據像素點相對於正方體中心的距離,對梯度幅值做加權處理。所以三維直方圖的值,即正方體的值共需要下面4 個步驟完成:1、計算落入該正方體內的鄰域像素的梯度幅值A;2、根據該像素相對於關鍵點的距離,對A 進行高斯加權處理,得到B;3、根據該像素相對於它所在的正方體的中心的貢獻大小,再對B 進行加權處理,得到C;4、對所有落入該正方體內的像素做上述處理,再進行求和運算ΣC,得到D。


圖7

        由於計算相對於正方體中心點的貢獻大小略顯繁瑣,因此在實際應用中,我們需要經過座標平移,把中心點平移到正方體的頂點上,這樣只要計算正方體內的點對正方體的8 個頂點的貢獻大小即可。根據三線性插值法,對某個頂點的貢獻值是以該頂點和正方體內的點爲對角線的兩個頂點,所構成的立方體的體積。如圖4 中,C000 的座標爲(0, 0, 0),C100 的座標爲(1, 0, 0),以此類推,C 的座標爲(r, c, θ),(這裏的r, c, θ 值的大小肯定是在0 和1 之間),則C 點與8 個頂點所構成的立方體的體積,也就是對8 個頂點的貢獻分別爲:

                                                                                                (公式30)

經過上面的三維直方圖的計算,最終我們得到了該特徵點的特徵矢量。爲了去除光照變化的影響,需要對特徵矢量進行歸一化處理,即:

                                                                          (公式31)

爲歸一化後的特徵矢量。儘管通過歸一化處理可以消除對光照變化的影響,但由於照相機飽和以及三維物體表面的不同數量不同角度的光照變化所引起的非線性光照變化仍然存在,它能夠影響到一些梯度的相對幅值,但不太會影響梯度幅角。爲了消除這部分的影響,我們還需要設一個t = 0.2 的閾值,保留Q 中小於0.2 的元素,而把Q 中大於0.2 的元素用0.2 替代。最後再對Q 進行一次歸一化處理,以提高關鍵點的可區分性。


備註:上面的4 描述符的建立 還未完全的理解透,所以是完整的照抄的,接下來將會分析opencv中的sift代碼,加深理解,然後回來修改。

2015年09月25日,第0次修改!


參考資料:

[1]  Lowe SIFT 原文:http://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf
[2]  SIFT特徵提取分析 http://blog.csdn.net/abcjennifer/article/details/7639681
[3]  王永明,王貴錦. 圖像局部不變性特徵與描述. [M] 國防工業出版社 
[4]  SIFT算法詳解 http://blog.csdn.net/zddblog/article/details/7521424
[5] sift論文翻譯 http://www.cnblogs.com/cuteshongshong/archive/2012/05/25/2506374.html
[6] 《Scale-space theory in computer vision  》
[7] 尺度空間:維基 https://en.wikipedia.org/wiki/Scale_space 
[8]  趙春江, opencv2.4.9 源碼分析,SIFT http://blog.csdn.net/zhaocj



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章