sift&surf檢測關鍵點及描述子


1sift介紹

SIFT全稱Scale-Invariant Feature Transform(尺度不變特征轉換)。它用來偵測與描述影像中的局部性特征,它在空間尺度中尋找極值點,並提取出其位置、尺度、旋轉不變量,此算法由 David Lowe在1999年所發表,2004年完善總結。

SIFT算法分解為如下四步:

(1)構建尺度空間

搜索所有尺度上的圖像位置,通過高斯微分函數來識別潛在的對於尺度和旋轉不變的興趣點,具體的過程如下。

A、采用高斯函數對圖像進行模糊以及降采樣處理得到高斯金字塔

 

B、采用DOG(Difference of Gaussian)即在高斯金子塔中的每組中相鄰兩層相減(“下一層減上一層”)生成高斯差分金字塔

 

(2)關鍵點定位

A、找到局部極值點

 

B、剔除極值點

通過Taylor展開式(插值函數)精確定位關鍵點,通過Hessian矩陣消除邊緣響應點。

 

(3)方向確定

對關鍵點進行梯度計算生成梯度直方圖統計領域內像素的梯度和方向,從而確定方向。

 

(4)關鍵點特征描述子

取特征點周圍44個區域塊,統計每小塊內8個梯度方向,用這448=128維向量作為Sift特征的描述子。

 

2surf介紹

SURF全稱Speeded Up Robust Features,為SIFT的加速版本。它改進了特征的提取和描述方式,用一種更為高效的方式完成特征的提取和描述。

SURF跟SIFT一樣分四步走:

1構建尺度空間

A、使用box filter濾波,然后使用Hessian矩陣獲取二階梯度特征(相當於LoG算子或SIFT里的DOG)

 

從左到右分別表示在y方向LoG算子(),xy方向的LoG算子,y方向近似的LoG算子,xy方向近似的LoG算子

(2)構建Hessian矩陣塔

surf在建塔的時候每層圖像大小不變,只是對模板的尺度不斷增大,相當於一個上采樣的過程。

 

第一塔中size分別為,而以后每塔中size邊長差距逐塔翻倍。

(2)關鍵點定位

A、找到局部極值點

這里和LoG,DoG相同,都是在生成尺度空間后,在三維上找極值點。

 

B、剔除極值點

這里和DoG不同的是不用剔除邊緣導致的極值點了,因為Hessian矩陣的行列式就已經考慮到邊緣的問題了,而DoG計算只是把不同方向變化趨勢給出來,后續還需要使用Hessian矩陣的特征值剔除邊緣產生的影響。

通過Taylor展開式(插值函數)精確定位關鍵點。

(3)方向確定

統計特征點圓形鄰域內的harr小波特征,按每60度划分一個扇區進行計算,最后得到值最大的那個扇區的方向做為主方向。

 

(4)關鍵點特征描述子

在特征點周圍取一個44的矩形區域塊,但是所取得矩形區域方向是沿着特征點的主方向。每個子區域統計25個像素的水平方向和垂直方向的haar小波特征,這里的水平和垂直方向都是相對主方向而言的。該haar小波特征為水平方向值之后、垂直方向值之后、水平方向絕對值之后以及垂直方向絕對值之和4個方向。

把這4個值作為每個子塊區域的特征向量,所以一共有4^4=64維向量作為Surf特征的描述子。

 

 

3siftsurf對比

(1)SURF不同點

A、在尺度空間中,使用box filtes與原圖像卷積,而不是使用DoG算子。

B、確定關鍵點方向時,Surf是利用不同方向bin中的haar小波響應的最大值最為方向,而Sift是統計周圍區域像素點的方向直方圖,找出最大方向bin作為主方向,而且還可以有多個方向。

C、特征描述子,Surf在關鍵點周圍取區域分成44塊小區域,在每個小區域計算采樣點的haar響應,統計對應的四個特征,共64維特征,而Sift在周圍1616的區域划分成4*4的子區域,每一個子區域提取長度為8的方向直方圖特征,排列起來形成128維特征向量。

(2)SURF速度更快

A、使用box filters相對於高斯濾波,再輔助以積分圖速度肯定提升不少。

B、Hessian矩陣的計算一般而言還是挺麻煩的,但這里可以使用積分圖計算,無論尺度是多少都可以使用幾個數的加減完成,速度很快。

C、確定關鍵點方向時使用haar特征同樣可以利用積分圖,簡單快速。

D、特征描述子使用64維取代128維特征降低了后續處理的數據規模。

 

4sift示例

#sift特征匹配
def siftFeature(queryPhoto,trainPhoto):
    img1 = cv.imread(queryPhoto,3) # queryImage
    img2 = cv.imread(trainPhoto,3) # trainImage
    # Initiate SIFT detector初始化SIFT檢測器
    # ref:https://docs.opencv.org/3.4.2/d5/d3c/classcv_1_1xfeatures2d_1_1SIFT.html
    sift = cv.xfeatures2d.SIFT_create()
    # find the keypoints and descriptors with SIFT獲取關鍵點與特征描述子
    # ref:https://docs.opencv.org/3.4.2/d0/d13/classcv_1_1Feature2D.html#a8be0d1c20b08eb867184b8d74c15a677
    kp1, des1 = sift.detectAndCompute(img1,None)
    kp2, des2 = sift.detectAndCompute(img2,None)
    # print(len(kp1))#輸出關鍵點的長度
    # Brute-force descriptor matcher蠻力描述子匹配 
    # ref:https://docs.opencv.org/3.4.2/d3/da1/classcv_1_1BFMatcher.html
    bf = cv.BFMatcher() 
    #從查詢集中查找每個描述符的k個最佳匹配。
    #ref:https://docs.opencv.org/3.4.2/db/d39/classcv_1_1DescriptorMatcher.html#aa880f9353cdf185ccf3013e08210483a
    matches = bf.knnMatch(des1,des2, k=2)
    # Apply ratio test
    good = []
    for m,n in matches:
        if m.distance < 0.75*n.distance:#剔除兩個匹配具體相差太遠的項
            good.append([m])
            
    #從兩個圖像中繪制找到的關鍵點匹配項,flags指定畫出匹配關鍵點的方式
    #ref:https://docs.opencv.org/3.4.2/d4/d5d/group__features2d__draw.html
    img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)

    return img3

  

5surf示例

#surf特征匹配
def surfFeature(queryPhoto,trainPhoto):
    img1 = cv.imread(queryPhoto,3) # queryImage
    img2 = cv.imread(trainPhoto,3) # trainImage
    # Initiate SURF detector初始化SURF檢測器
    #ref:https://docs.opencv.org/3.4.2/d5/df7/classcv_1_1xfeatures2d_1_1SURF.html
    surf=cv.xfeatures2d.SURF_create(400)#初始Hessian矩陣的閾值
    # find the keypoints and descriptors with SURF
    kp1, des1 = surf.detectAndCompute(img1,None)
    kp2, des2 = surf.detectAndCompute(img2,None)
    # print(len(kp1))
    # surf.setHessianThreshold(5000) #指定Hessian矩陣的閾值
    # print(surf.getHessianThreshold())
    
    # BFMatcher with default params
    bf = cv.BFMatcher()
    matches = bf.knnMatch(des1,des2, k=2)
    # Apply ratio test
    good = []
    for m,n in matches:
        if m.distance < 0.75*n.distance:
            good.append([m])
    print(type(good[0][0]))# cv2.DMatch      
    img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)

    return img3

 

參考:

Introduction to SIFT (Scale-Invariant Feature Transform)

https://docs.opencv.org/3.3.0/da/df5/tutorial_py_sift_intro.html

圖像相似度算法--SIFT算法詳解

https://blog.csdn.net/counte_rking/article/details/78834644

SIFT特征點提取

https://blog.csdn.net/lingyunxianhe/article/details/79063547

DoG (Difference of Gaussian)角點檢測

https://blog.csdn.net/abcjennifer/article/details/7639488

Surf特征提取分析

https://www.cnblogs.com/YiXiaoZhou/p/5903690.html

SURF算法

https://www.cnblogs.com/jinjidexuetu/p/90ace4e8de574e3d5f4e6ac16a0dc157.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM