尺度不變特徵變換(Scale-invariant feature transform, 簡稱SIFT)是圖像局部特徵提取的現代方法——基於區域/圖像塊的分析。在上篇筆記裏咱們使用的圖像之間對應點的匹配方法,不適用於不一樣尺度的圖像。有許多應用場景須要對不一樣尺度(即分辨率、縮放、旋轉角度、亮度等均可能存在不一樣)的圖像進行特徵識別和匹配,這就須要一種特徵提取方法,經過這種方法提取出來的特徵描述,能夠不受尺度的影響,SIFT算法就是這種方法的實現。SHIT算法有以下的特色:html
SIFT特徵是圖像的局部特徵,其對旋轉、尺度縮放、亮度變化保持不變性,對視角變化、仿射變換、噪聲也保持必定程度的穩定性;算法
獨特性(Distinctiveness)好,信息量豐富,適用於在海量特徵數據庫中進行快速、準確的匹配;數據庫
多量性,即便少數的幾個物體也能夠產生大量的SIFT特徵向量;segmentfault
高速性,經優化的SIFT匹配算法甚至能夠達到實時的要求;dom
可擴展性,能夠很方便的與其餘形式的特徵向量進行聯合。學習
SIFT算法的應用很是普遍,包括物體識別、機器人地圖感知與導航、全景拼接、3D建模、手勢識別、影像追蹤和動做比對等,原書後面章節的算法也會屢次用到它。SIFT算法的過程較複雜,本文只是粗略介紹其關鍵步驟,以便引出SURF——基於SIFT的改進算法。優化
SIFT的算法仍是比較複雜的,但也讓人大開眼界,權威的和詳細的介紹應該直接看英文論文,個人筆記記錄的也只是其算法的要點,目的是爲了理解算法的思想,爲了對涉及到的數學有一個大概的瞭解。url
降採樣或隔點採樣,將一幅圖像降爲一半大小的圖像,連續使用幾回降採樣,每次獲得的圖像大小都降爲前一張大小的一半,最後獲得一組降採樣的圖像。降採樣的目的是爲了綜合全部不一樣清晰度的圖像進行關鍵點提取,這種關鍵點攜帶了不一樣清晰度的信息,對縮放具備不變性。spa
在以前的筆記介紹過,原圖像與高斯核(2維高斯算子)做卷積(高斯濾波)的結果即爲模糊圖像,實爲平滑效果,高斯濾波屬於低通濾波,它能夠過濾掉必定的噪聲。若是把兩張使用不一樣sigma的模糊圖像記爲Bσ和Bkσ, DOG操做即爲兩張模糊圖像之差,記:code
Gσ = Bkσ - Bσ
Gσ爲DOG圖像,它包含的特徵是目標的輪廓。
SIFT先對降採樣後的每張圖像使用不一樣的sigma進行高斯模糊,結果是每一個降採樣圖像對應一組模糊圖像:
而後對每組模糊圖像的相鄰圖像做DOG,結果是每一個降採樣圖像對應一組DOG圖像,如圖:
把每一組圖像堆疊起來,位於塔底的是第一組(first octave),往上是第二組,第三組...每一組的圖像大小爲前一組的一半,看起來像金字塔:
如圖Gaussian列(左邊)稱爲高斯金字塔,DOG列(右邊)稱爲DOG金字塔。
SIFT分別對每組DOG圖像提取關鍵點,以第一組爲例,將第一組DOG圖像上下對齊疊加在一塊兒,造成DOG空間,DOG空間有兩個域:圖像域和尺度域。圖像域指圖像自己的二維平面像素,尺度域指垂直於圖像域的第三維度構成的像素。SIFT使用局部極值檢測來定位找到關鍵點,以下圖所示:
X位置所在像素即爲當前要檢測的點,以X爲中心的周圍像素(包括圖像域和尺度域)造成了一個局部空間(像3X3魔方),若是X爲此局部空間的極值(最大值或最小值),那麼X即爲關鍵點之一。
SIFT的提取的特徵(關鍵點)須要對尺度保持不變性,因此這裏講的關鍵點,比以前筆記介紹的角點和興趣點稍爲複雜些,SIFT關鍵點須要攜帶尺度信息,包括縮放、方向等信息,主要由它周圍的像素來貢獻。若是用一個向量來存儲這些信息,此向量稱爲關鍵點描述(key point descriptor,簡稱KPD),KPD生成步驟:
在關鍵點所在圖像上,劃出以關鍵點爲中心的16x16的矩形圖像:
將16x16矩形圖像劃分爲16小格,每小格爲4x4,並計算每一個像素的梯度和幅度(即像素值變化的方向及大小):
對每一個小格進行統計,統計8個方向的幅度,造成幅度直方圖:
將16小格的幅度直方圖鏈接起來,用向量表示,即爲KPD,共有128(8x16)維:
使用向量表示爲: R = (r1, r2, ..., r128)
爲了讓關鍵點對方向具備不變性,在選取16x16矩形區域的時候,將矩形的方向旋轉到與關鍵點主方向一致。SIFT定義關鍵點主方向爲:以關鍵點爲中心的周圍像素所貢獻的主方向。
可採用梯度直方圖統計法,統計以關鍵點爲原點,必定區域內的圖像像素點對關鍵點方向生成所做的貢獻,貢獻最大的那個方向即爲關鍵點主方向。
關鍵點的匹配問題,已經轉爲KPD的匹配問題,兩KPD的類似程度,使用歐式距離進行計算。設有兩個KPD分別爲R = (r1, r2, ..., r128)和S = (s1, s2, ..., s128),R與S的歐式距離計算公式爲:
d = sqrt((r1 - s1)^2 + (r2 - s2)^2 + ... + (r128 - s128)^2)
因此,要找出兩張不一樣尺度圖像間的對應點(具備對應關係的關鍵點),分下面幾步:
分別檢測兩張圖像的關鍵點,並計算出每一個關鍵點的KPD,分別獲得兩個KPD集合SET1和SET2
爲SET1中每一個KPD,從SET2找最佳匹配(即歐式距離最小的爲最佳匹配),而後反過來,爲SET2每一個KPD,從SET1中找最佳匹配,只有彼此認爲是最佳匹配的那些KPD對纔是對應點
爲提升匹配準確率,能夠設定一個閾值,歐式距離大於此閾值的那些匹配對,將不考慮。
爲提升算法效率,可使用kd樹和RANSAC( Random Sample Consensus, 隨機抽樣一致)方法。
SURF(Speeded Up Robust Features)是對SIFT的一種改進,主要特色是快速。SURF與SIFT主要有如下幾點不一樣處理:
SIFT在構造DOG金字塔以及求DOG局部空間極值比較耗時,SURF的改進是使用Hessian矩陣變換圖像,極值的檢測只需計算Hessian矩陣行列式,做爲進一步優化,使用一個簡單的方程能夠求出Hessian行列式近似值,使用盒狀模糊濾波(box blur)求高斯模糊近似值。
SURF不使用降採樣,經過保持圖像大小不變,但改變盒狀濾波器的大小來構建尺度金字塔。
在計算關鍵點主方向以及關鍵點周邊像素方向的方法上,SURF不使用直方圖統計,而是使用哈爾(haar)小波轉換。
SIFT的KPD達到128維,致使KPD的比較耗時,SURF使用哈爾(haar)小波轉換獲得的方向,讓SURF的KPD降到64維,減小了一半,提升了匹配速度。
SIFT算法是有專利的,正規使用是要交專利費的,因此有人提出了一種可做爲SIFT替代的算法——ORB,ORB沒有專利問題,考慮到本文篇幅過長,圖片過多,此算法的介紹和示例將在下一筆記介紹。
可能也是由於專利問題,skimage庫有ORB算法,但沒有SIFT和SURF。雖然OpenCV都包含了上述算法,但OpenCV目前不在個人學習計劃中。
原書示例使用了一個第三方實現的SIFT算法庫,我認爲在實際使用可能價值不高,另外,書上也沒有介紹ORB(也許是由於在寫此書時,ORB尚未出來),但我認爲ORB更有研究的必要,由於無專利問題,它將會是一個被普遍使用的算法,因此本文沒有給出SIFT代碼示例,但計劃在下篇筆記介紹ORB和給出示例。
你還能夠看我其它的筆記。