如何在OpenCV Python中实现基于FLANN的特征匹配
我们使用尺度不变特征变换( SIFT )和FLANN(快速近似最近邻)来实现两幅图像之间的特征匹配。使用SIFT来找到特征关键点和描述子。使用基于FLANN的knn来匹配两幅图像中的描述子。我们使用cv2.FlannBasedMatcher()作为基于FLANN的匹配器。
步骤
要在使用SIFT特征检测器和基于FLANN的匹配器之间实现两幅图像的特征匹配,可以按照以下步骤进行:
- 导入所需的库 OpenCV、Matplotlib 和 NumPy 。确保您已经安装了它们。
-
使用 cv2.imread() 方法将两个输入图像作为灰度图像读入。指定图像的完整路径。
-
使用 sift=cv2.SIFT_create() 初始化默认值的SIFT对象。
-
使用 sift.detectAndCompute() 在两个输入图像中检测和计算关键点 kp1 和 kp2 以及描述子 des1 和 des2。
-
创建一个基于FLANN的匹配器对象 flann = cv2.FlannBasedMatcher() 并使用 flann.knnMatch(des1,des2,k=2) 匹配描述子。它返回匹配结果。对匹配结果应用比例测试以获取最佳匹配。使用 cv2.drawMatchesKnn() 绘制匹配结果。
-
可视化关键点匹配。
让我们看一些使用SIFT特征检测器和基于FLANN的匹配器来匹配两幅图像的关键点的示例。
输入图像
我们将在下面的示例中使用以下图像作为输入文件。
示例
在这个示例中,我们使用 SIFT 算法检测两个输入图像的关键点和描述符,并使用基于 FLANN匹配器 和 knn 方法匹配描述符。同时,我们还应用比例测试只找出良好的匹配项。我们还绘制了关键点和匹配项。
# import required libraries
import numpy as np
import cv2
from matplotlib import pyplot as plt
# read two input images
img1 = cv2.imread('car.jpg',0)
img2 = cv2.imread('car-rotated-crop.jpg',0)
# Initiate SIFT detector
sift = cv2.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
# FLANN parameters
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50) # or pass empty dictionary
# apply FLANN based matcher with knn
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
# Need to draw only good matches, so create a mask
matchesMask = [[0,0] for i in range(len(matches))]
# ratio test as per Lowe's paper
for i,(m,n) in enumerate(matches):
if m.distance < 0.1*n.distance:
matchesMask[i]=[1,0]
draw_params = dict(matchColor = (0,255,0),singlePointColor = (255,0,0),matchesMask = matchesMask,flags = 0)
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params)
plt.imshow(img3),plt.show()
输出
运行上述Python程序时,它将产生以下输出窗口:
输出