我们知道您的关键点分别存储在第一张和第二张图片的特征匹配列表中,kp1
以及kp2
它们的位置。从cv2.ORB
角度来看,特征描述符是2D矩阵,其中每一行都是在第一张和第二张图像中检测到的关键点。
在您的情况下(因为您正在使用)cv2.BFMatch
,matches
返回一个cv2.DMatch
对象列表,其中每个对象包含多个成员,其中两个是重要成员:
因此,queryIdx
并trainIdx
告诉你哪个ORB的特征,第一和第二图像之间的匹配。你会使用这些索引kp1
并kp2
和获得pt
成员,这是一个元组(x,y)
决定比赛的实际空间坐标的坐标。
您所要做的就是遍历中的每个cv2.DMatch
对象matches
,kp1
并为它们附加一个坐标列表,kp2
然后就可以完成了。
像这样:
# Initialize lists
list_kp1 = []
list_kp2 = []
# For each match...
for mat in matches:
# Get the matching keypoints for each of the images
img1_idx = mat.queryIdx
img2_idx = mat.trainIdx
# x - columns
# y - rows
# Get the coordinates
(x1, y1) = kp1[img1_idx].pt
(x2, y2) = kp2[img2_idx].pt
# Append to each list
list_kp1.append((x1, y1))
list_kp2.append((x2, y2))
请注意,我本来可以做的list_kp1.append(kp1[img1_idx].pt)
和一样list_kp2
,但是我想非常清楚地说明如何解释空间坐标。您还可以更进一步,进行列表理解:
list_kp1 = [kp1[mat.queryIdx].pt for mat in matches]
list_kp2 = [kp2[mat.trainIdx].pt for mat in matches]
list_kp1
将包含与中的对应位置匹配的特征点的空间坐标list_kp2
。换句话说,元件i
的list_kp1
包含从特征点的空间坐标img1
,从与对应的特征点匹配img2
在list_kp2
其空间坐标是在元件i
。
作为次要说明,我在写变通方法时使用了这个概念,drawMatches
因为对于OpenCV 2.4.x,不存在C ++函数的Python包装器,因此我在确定匹配特征的空间坐标时使用了上述概念。在两个图像之间编写我自己的实现。
如果喜欢,请检查一下!