SIFT概述
SIFT特征是非常穩定的圖像特征,在圖像搜索、特征匹配、圖像分類檢測等方面應用十分廣泛,但是它的缺點也是非常明顯,就是計算量比較大,很難實時,所以對一些實時要求比較高的常見SIFT算法還是無法適用。
如今SIFT算法在深度學習特征提取與分類檢測網絡大行其道的背景下,已經越來越有雞肋的感覺,但是它本身的算法知識還是很值得我們學習,對我們也有很多有益的啟示,本質上SIFT算法是很多常見算法的組合與巧妙銜接,這個思路對我們自己處理問題可以帶來很多有益的幫助。
特別是SIFT特征涉及到尺度空間不變性與旋轉不變性特征,是我們傳統圖像特征工程的兩大利器,可以擴展與應用到很多圖像特征提取的算法當中,比如SURF、HOG、HAAR、LBP等。
夸張一點的說SIFT算法涵蓋了圖像特征提取必備的精髓思想,從特征點的檢測到描述子生成,完成了對圖像的準確描述,早期的ImageNet比賽中,很多圖像分類算法都是以SIFT與HOG特征為基礎,所有SIFT算法還是值得認真詳細解讀一番的。SIFT特征提取歸納起來SIFT特征提取主要有如下幾步:
構建高斯多尺度金字塔
關鍵點精準定位與過濾
關鍵點方向指派
描述子生成
構建高斯多尺度金字塔
常見的高斯圖像金字塔是每層只有一張圖像,大致如下:
上述的是通過圖像金字塔實現了多分辨率,如果我們在每一層高斯金字塔圖像生成的時候,給予不同的sigma值,這樣不同的sigam就會產生不同模糊版本的圖像,在同一層中就是實現不同尺度的模糊圖像,再結合高斯金字塔,生成多個層多個尺度的金字塔,就是實現了圖像的多尺度金字塔。同一張圖像不同尺度高斯模糊如下:
為了在每層圖像中檢測 S 個尺度的極值點,DoG 金字塔每層需 S+2 張圖像,因為每組的第一張和最后一張圖像上不能檢測極值,DoG 金字塔由高斯金字塔相鄰兩張相減得到,則高斯金字塔每層最少需 S+3 張圖像,實際計算時 S 通常在2到5之間。SIFT算法中生成高斯金字塔的規則如下(尺度空間不變性):
關鍵點精準定位與過濾
對得到的每層DOG圖像,計算窗口3x3x3范圍除去中心點之外的26點與中心點比較大小,尋找最大值或者最小值(極值點),如下圖:
即周圍26個點(青色)要小于或者大于中心像素點,這樣就得到初步的極值點候選,然后進行亞像素級別的精準定位。
原因在于圖像得到像素坐標是離散的,尺度空間也是離散的間隔,每個極值點P(x, y, s)三維空間中不一定是真正的連續空間的極值點,以二維的曲線為例,得到藍色是離散空間極值點,實際極值點是紅色點,如下圖所示:
從上圖我們也可以看出,在連續空間的極值點必然是導數過零點,
對于|D(extremal)| < 0.03可以作為低對比度點或者弱邊緣舍棄。
關鍵點方向指派
前面我們已經詳細解釋了SIFT特征點是如何提取的,有了特征點之后,我們對特征點周圍的像素塊計算角度方向直方圖,在計算直方圖之前首先需要對圖像進行梯度計算,這里可以使用SOBEL算子,然后根據dx與dy計算梯度和與角度,這里使用的高斯權重,所以在梯度之前,首先需要對ROI區域進行高斯模糊,然后再計算角度(x軸,Bins)-梯度(Y軸)直方圖,直方圖的最高峰(max peak)對應的角度就是關鍵點的角度方向,對于大于max peak*85%的bin也作為方向指派給關鍵點,這樣同一個關鍵點因為有多個方向在描述子生成的時候就會生成多個描述子,從而增加了特征的穩定性與抗干擾能力。圖示如下:
描述子生成
選擇關鍵點小區域,根據窗口大小不同可以分為4x4大小不同的Cell,每個Cell生成一個角度方向直方圖(8個BIN),對它們進行排序以后(旋轉不變性描述子),生成128個向量特征數據,作為該關鍵點的唯一描述
根據排序以后生成描述子的規則不同,又可以分為
原圖正常順序描述子
水平反射順序描述子
垂直反射順序描述子
如下圖所示:
OpenCV中調用
OpenCV已經實現了SIFT算法,但是在OpenCV3.0之后因為專利授權問題,該算法在擴展模塊xfeature2d中,需要自己編譯才可以使用。
但是在OpenCV4.4之后因為專利過期,SIFT算法又回到了正式發布安裝包中,無需編譯源碼,即可使用!首先需要創建一個SIFT檢測器對象,通過調用
通過detect方法提取對象關鍵點
用drawKeypoints繪制關鍵點
通過compute提取描述子,
通過暴力匹配根據描述子匹配
代碼演示如下
importcv2ascv box=cv.imread("D:/images/box.png"); box_in_sence=cv.imread("D:/images/box_in_scene.png"); cv.imshow("box",box) cv.imshow("box_in_sence",box_in_sence) #創建SIFT特征檢測器 sift=cv.xfeatures2d.SIFT_create() #特征點提取與描述子生成 kp1,des1=sift.detectAndCompute(box,None) kp2,des2=sift.detectAndCompute(box_in_sence,None) #暴力匹配 bf=cv.DescriptorMatcher_create(cv.DescriptorMatcher_BRUTEFORCE) matches=bf.match(des1,des2) #繪制最佳匹配 matches=sorted(matches,key=lambdax:x.distance) result=cv.drawMatches(box,kp1,box_in_sence,kp2,matches[:15],None) cv.imshow("-match",result) cv.waitKey(0) cv.destroyAllWindows()
SIFT算法啟示
多尺度金字塔,特征金字塔技術,遷移不變性與旋轉不變性特征,這兩點現在卷積神經網絡及其變種的網絡中也是很常見的特征工程技術。
審核編輯:劉清
-
OpenCV
+關注
關注
31文章
635瀏覽量
41556 -
LBP
+關注
關注
0文章
14瀏覽量
8967 -
SIFT算法
+關注
關注
0文章
8瀏覽量
7460
原文標題:OpenCV4中 SIFT特征算法詳解與使用
文章出處:【微信號:CVSCHOOL,微信公眾號:OpenCV學堂】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論