OpenCV Python 使用SIFT实现两个图像之间的特征匹配
我们使用尺度不变特征变换( SIFT )特征描述符和暴力匹配( Brute Force )特征匹配器来实现两个图像之间的特征匹配。SIFT被用来在图像中找到特征关键点和描述符。使用暴力匹配器来匹配两个图像的描述符。
步骤
要使用SIFT特征检测器和暴力匹配器实现两个图像之间的特征匹配,可以按照以下步骤进行:
- 导入所需的库: OpenCV, Matplotlib , and NumPy 。确认已经安装了这些库。
-
使用 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 算法检测两个输入图像的关键点和描述子,并使用Brute Force匹配器进行描述子的匹配。我们还绘制了最佳的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 算法检测两个输入图像的关键点和描述符,并使用基于 Brute Force 的 matcher 和 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()
输出
在执行时,它将产生以下 输出 −