使用Python和OpenCV實現SIFT與ORB


目錄如下:

程序運行環境

  • python 3.7.3
  • numpy 1.16.6
  • opencv-python 4.4.0.40

SIFT_pratice.py

程序

import cv2
import numpy as np

"""
該程序使用dataset中的1.jpg和2.jpg,使用SIFT對這2張圖片進行特征檢測和特征提取,使用暴力匹配法對這2張圖片進行特征匹配,最后計算匹配程度較高的特征點的單應性矩陣
"""

# 讀取圖片
img1 = cv2.imread('./dataset/1.jpg')
img2 = cv2.imread('./dataset/2.jpg')

# 創建SIFT
sift = cv2.xfeatures2d.SIFT_create()

# 檢測關鍵點並提取特征
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# 特征匹配:暴力匹配
bf = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_BRUTEFORCE)
matches = bf.match(des1, des2)

# 繪制特征匹配結果
matches = sorted(matches, key=lambda x: x.distance)
good_matches = matches[:50]  # 只取前XX個匹配
result = cv2.drawMatches(img1, kp1, img2, kp2, good_matches,
                         None, matchColor=(0, 0, 255), singlePointColor=(255, 0, 0))  # 只畫前XX個匹配
cv2.imshow('result', result)

# 計算單應性矩陣
pts1, pts2 = [], []
for f in good_matches:
    pts1.append(kp1[f.queryIdx].pt)
    pts2.append(kp2[f.trainIdx].pt)
H, _ = cv2.findHomography(np.float32(pts1), np.float32(pts2), cv2.RHO)
print('單應性矩陣:')
print(H)

cv2.waitKey(0)

程序功能

該程序使用dataset中的1.jpg和2.jpg,使用SIFT對這2張圖片進行特征檢測特征提取,使用暴力匹配法對這2張圖片進行特征匹配,最后計算匹配程度較高的特征點的單應性矩陣

運行結果

SIFT_pratice運行結果

ORB_pratice.py

程序

import cv2
import numpy as np

"""
該程序使用dataset中的3.jpg和4.jpg,使用ORB對這2張圖片進行特征檢測和特征提取,使用暴力匹配法對這2張圖片進行特征匹配,,最后計算匹配程度較高的特征點的單應性矩陣
"""

# 讀取圖片
img1 = cv2.imread('./dataset/3.jpg')
img2 = cv2.imread('./dataset/4.jpg')

# 創建ORB
orb = cv2.ORB_create()

# 檢測關鍵點並提取特征
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

# 特征匹配:暴力匹配、漢明距離
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)

# 繪制特征匹配結果
matches = sorted(matches, key=lambda x: x.distance)
good_matches = matches[:50]  # 只取前XX個匹配
result = cv2.drawMatches(img1, kp1, img2, kp2, good_matches, None)
cv2.imshow('result', result)

# 計算單應性矩陣
pts1, pts2 = [], []
for f in good_matches:
    pts1.append(kp1[f.queryIdx].pt)
    pts2.append(kp2[f.trainIdx].pt)
H, _ = cv2.findHomography(np.float32(pts1), np.float32(pts2), cv2.RHO)
print('單應性矩陣:')
print(H)

cv2.waitKey(0)

程序功能

該程序使用dataset中的3.jpg和4.jpg,使用ORB對這2張圖片進行特征檢測特征提取,使用暴力匹配法對這2張圖片進行特征匹配,,最后計算匹配程度較高的特征點的單應性矩陣。

運行結果

ORB_pratice運行結果

相關理論

SIFT

  • 作者

    David Lowe

  • 發表

    David Lowe於1999年發表於ICCV,經過整理和完善,在2004年發表於IJCV。

  • 特點

    對圖片大小和旋轉不敏感,而且對光照、噪聲等影響的抗擊能力也非常優秀。

  • 實現

    可以分為4個步驟

    1. Scale-space extrema detection
      • 使用高斯差分函數(DoG)來計算並搜索所有尺度上的圖像位置,用於識別對尺度和方向不變的潛在興趣點。
      • 由於平滑區域臨近像素之間變化不大,但是在邊、角、點這些特征較豐富的地方變化較大,因此通過DOG比較臨近像素可以檢測出候選關鍵點。
    2. Keypoint localization
      • 通過一個擬合精細的模型在每個候選位置上確定位置和尺度,關鍵點的選擇依賴於它們的穩定程度。
      • 根據關鍵點的穩定性來選擇關鍵點。在每個候選位置,通過一個模型來確定位置和比例。
    3. Orientation assignment
      • 基於局部圖像的梯度方向,將一個或多個方向分配給每個關鍵點位置。
      • 后續所有對圖像數據的操作都是相對於關鍵點的方向、尺度和位置進行變換,從而為這些變換提供了不變性。
    4. Keypoint descriptor
      • 在每個關鍵點周圍的區域內以選定的比例計算局部圖像梯度,這些梯度被變換成一種表示。
      • 這種表示允許比較大的局部形狀的變形和光照變化。

ORB

  • 作者

    Ethan Rublee在2011年發表於ICCV

  • 提出

    • SIFT算法

      不管是特征提取還是特征描述,SIFT都十分復雜,並且特征向量的匹配采用浮點數之間計算歐式距離,較為耗時。

    • FAST特征提取算法

      於2006年ECCV上提出,作為十分高效的特征點提取算法,其並沒有提取出特征點的主方向,因而后續無法根據主方向對特征點進行描述。

    • BRIEF特征描述算法

      於2010年CVPR上提出,其是一種十分簡單的特征點描述算法,其輸出向量為二進制、進而極大的節省了向量的保存空間和簡化了特征向量間的距離計算,但該算法對方向的改變十分敏感,因此對特征點的描述將不具有旋轉不變性

    • ORB

      ORB算法在FAST算法的基礎上,提取了特征點的方向。同時根據特征點的方向,采用改進BRIEF算法的Rotated BRIEF算法對特征進行描述。ORB取長補短,既高效地完成了特征提取和特征描述,又使得特征描述向量具有旋轉不變性。

  • 特點

  • 實現

    可以分為4個步驟

    1. 構造圖像金字塔

      在不同降采樣大小的圖像下進行FAST特征點提取,進而得到特征點的尺度信息

    2. FAST算法

      1. 對於圖像中一個像素點p,其灰度值為Ip
      2. 以該像素點為中心考慮一個半徑為3的離散化的Bresenham圓,圓邊界上有16個像素
      3. 設定一個合適的閾值t,如果圓上有n個連續像素點的灰度值小於Ip−t或者大於Ip+t,那么這個點即可判斷為特征點(角點),n的值可取9、11、12。

      運行完FAST算法,會得到大量特征點,需要用NMS篩選

    3. 計算旋轉角度

      • 利用灰度質心法求一個圓形區域的質心,連接質心和圓心形成一個向量,這個向量的角度就是角點的角度。
      • 其中圓的半徑取為15,因為整個patch一般取的是31×31的。
      • 這個角度可以用來指導BRIEF描述子的提取,保證每次都在相同的方向上計算描述子,實現角度不變性。
    4. 計算旋轉后的BRIEF描述子

      • BRIEF
        • 在特征點的描述區域范圍(系數*尺度)內,隨機生成256個位置對。對於每對位置,如果位置1點的像素值大於位置2點的像素值,則該對位置的輸出為1,反之為0。
        • 一共有256個位置對,所以最終特征描述將用一個256向量組成,向量的每個元素都是二進制數。
        • 對於隨機生成的256個位置對,BRIEF作者嘗試了五種方法,最終選擇二維高斯函數作為位置對的分布。
        • 位置對的生成為初始隨機生成,但生成后位置對便固定下來,最終匹配的時候所有特征點均采用相同的位置對。
      • Steered BRIEF
        • BRIEF算法中,位置對是以右方向為x軸。
        • 在Steered BRIEF算法中,特征點的位置對以特征點的主方向為x軸,因此當主方向為θ時,原BRIEF算法中的位置對的位置也需要根據θ進行坐標轉換。
          • 具體方法是已選好的256個位置對乘上旋轉矩陣,從而得到以特征點的主方向為x軸時坐標系下的位置。
          • 通過該256個位置對對特征點進行描述,由於位置對的位置已經根據方向發生了相應的改變,因此Steered BRIEF算法具有一定的旋轉不變性。
      • Rotated BRIEF
        • 在Steered BRIEF算法,其256維度的特征描述向量,每一個位置對的位置與其輸出有一定的相關性,進而使得特征描述向量的信息熵減少。由此, Rotated BRIEF 提出用統計學習的方法選擇位置對代替二維高斯隨機分布選擇位置對。

單應性變換

  • 單應性變換是什么

    • 單應性變換是一個平面內的點映射到另一個平面內的二維投影變換,對應的變換矩陣稱為單應性矩陣
    • 在這里,平面是指圖像或者三維中的平面表面。
  • 單應性變換的作用

    單應性變換具有很強的實用性,比如圖像配准,圖像糾正和紋理扭曲,以及創建全景圖像。

  • 關於齊次坐標

    • 對於圖像平面內的點,齊次坐標是個非常有用的表示方式。
    • 點的齊次坐標是依賴於尺度定義的,所以x=[x,y,w]=[αx,αy,αw]=[x/w,y/w,1] 都表示同一個點。因此單應性矩陣H也依賴尺度定義。

作者:@臭咸魚

轉載請注明出處:https://www.cnblogs.com/chouxianyu/

歡迎討論和交流!



免責聲明!

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



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