OpenCV Python – 使用 SIFT 實現兩幅影像之間的特徵匹配


我們使用尺度不變特徵變換 (SIFT) 特徵描述符和蠻力特徵匹配器來實現兩幅影像之間的特徵匹配。SIFT用於查詢影像中的特徵關鍵點和描述符。蠻力匹配器用於匹配兩幅影像中的描述符。

步驟

要使用SIFT特徵檢測器和蠻力匹配器實現兩幅影像之間的特徵匹配,您可以按照以下步驟操作:

  • 匯入所需的庫OpenCV、MatplotlibNumPy。確保您已安裝它們。

  • 使用cv2.imread()方法讀取兩幅輸入影像作為灰度影像。指定影像的完整路徑。

  • 使用sift=cv2.SIFT_create()以預設值初始化 SIFT 物件。

  • 使用sift.detectAndCompute()檢測並計算兩幅輸入影像中的關鍵點'kp1'和'kp2'以及描述符'des1'和'des2'。

  • 建立一個 BFmatcher 物件bf = cv2.BFMatcher(),並使用此 BFmatcher 物件作為bf.match(des1, des2)來匹配描述符。它返回匹配項。根據它們的距離對匹配項進行排序。

  • 使用cv2.drawMatches()在原始輸入影像上繪製匹配項。

  • 可以選擇使用 BFmatcher 物件方法bf.knnMatch(des1,des2, k=2)來匹配描述符。對匹配項應用比率測試以獲得最佳匹配項。使用cv2.drawMatchesKnn()繪製匹配項。

  • 視覺化關鍵點匹配。

讓我們看一些示例,以使用SIFT特徵檢測器和蠻力匹配器匹配兩幅影像的關鍵點。

輸入影像

我們在下面的示例中使用以下影像作為輸入檔案。



示例

在此示例中,我們使用SIFT演算法檢測兩幅輸入影像的關鍵點和描述符,並使用蠻力匹配器匹配描述符。我們還繪製了最佳的 50 個關鍵點匹配。在此示例中,我們將flags=2傳遞給drawMatches()以繪製匹配項。

# import required libraries import numpy as np import cv2 import matplotlib.pyplot as plt # read two input images as grayscale img1 = cv2.imread('bmw.jpg',0) img2 = cv2.imread('bmw-rotated.jpg',0) # Initiate SIFT detector sift = cv2.SIFT_create() # detect and compute the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(img1,None) kp2, des2 = sift.detectAndCompute(img2,None) # create BFMatcher object bf = cv2.BFMatcher() # Match descriptors. matches = bf.match(des1,des2) # sort the matches based on distance matches = sorted(matches, key=lambda val: val.distance) # Draw first 50 matches. out = cv2.drawMatches(img1, kp1, img2, kp2, matches[:50], None, flags=2) plt.imshow(out), plt.show()

輸出

執行後,它將產生以下輸出


示例

在此示例中,我們使用SIFT演算法檢測兩幅輸入影像的關鍵點和描述符,並使用基於蠻力匹配器以及knn匹配描述符。我們還繪製了最佳的 50 個關鍵點匹配。在此示例中,我們將flags=0傳遞給drawMatches()以繪製匹配項。

# import required libraries import numpy as np import cv2 import matplotlib.pyplot as plt # read two input images as grayscale img1 = cv2.imread('bmw.jpg',0) # queryImage img2 = cv2.imread('bmd-rotated.jpg',0) # trainImage # Initiate SIFT detector sift = cv2.SIFT_create() # detect and compute the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(img1,None) kp2, des2 = sift.detectAndCompute(img2,None) # create BFMatcher object bf = cv2.BFMatcher() matches = bf.knnMatch(des1,des2, k=2) # Apply ratio test good = [] for m,n in matches: if m.distance < 0.1*n.distance: good.append([m]) # cv2.drawMatchesKnn expects a list of lists as matches. img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=0) plt.imshow(img3),plt.show()

輸出

執行後,它將產生以下輸出


更新於: 2022-12-05

8K+ 瀏覽量

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告