如何从 OpenCV Python 中的特征匹配中获取像素坐标

Posted

技术标签:

【中文标题】如何从 OpenCV Python 中的特征匹配中获取像素坐标【英文标题】:How to get pixel coordinates from Feature Matching in OpenCV Python 【发布时间】:2015-08-23 08:38:39 【问题描述】:

我需要获取特征匹配器在提供的代码中选择的像素的xy 坐标列表。我正在使用 Python 和 OpenCV。谁能帮帮我?

img1=cv2.imread('DSC_0216.jpg',0)
img2=cv2.imread('DSC_0217.jpg',0)

orb=cv2.ORB(nfeatures=100000)
kp1,des1=orb.detectAndCompute(img1,None)
kp2,des2=orb.detectAndCompute(img2,None)

img1kp=cv2.drawKeypoints(img1,kp1,color=(0,255,0),flags=0)
img2kp=cv2.drawKeypoints(img2,kp2,color=(0,255,0),flags=0)
cv2.imwrite('m_img1.jpg',img1kp)
cv2.imwrite('m_img2.jpg',img2kp)

bf=cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches=bf.match(des1,des2)
matches=sorted(matches, key= lambda x:x.distance)

【问题讨论】:

【参考方案1】:

我们知道您的关键点存储在kp1kp2 中,它们分别是第一张和第二张图像的特征匹配列表。在cv2.ORB 透视图中,特征描述符是二维矩阵,其中每一行是在第一张和第二张图像中检测到的关键点。

在您的情况下,因为您使用的是 cv2.BFMatchmatches 返回一个 cv2.DMatch 对象列表,其中每个对象包含多个成员,其中有两个重要成员:

queryIdx - 匹配的kp1 兴趣点矩阵的索引或 trainIdx - 匹配的kp2 兴趣点矩阵的索引或

因此,queryIdxtrainIdx 会告诉您在第一张和第二张图像之间哪些 ORB 特征匹配。您可以使用这些索引到 kp1kp2 并获得 pt 成员,它是确定匹配的实际空间坐标的 (x,y) 坐标的元组。

您所要做的就是遍历matches 中的每个cv2.DMatch 对象,并附加到kp1kp2 的坐标列表中,然后就完成了。

类似这样的:

# 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 中对应位置匹配的特征点的空间坐标。换句话说,list_kp1 的元素i 包含来自img1 的特征点与list_kp2 中对应的img2 特征点的空间坐标,其空间坐标在元素i 中。


作为一个小旁注,我在为drawMatches 编写解决方法时使用了这个概念,因为对于 OpenCV 2.4.x,C++ 函数的 Python 包装器不存在,所以我利用上述概念来定位两个图像之间匹配特征的空间坐标来编写我自己的实现。

喜欢就去看看吧!

module' object has no attribute 'drawMatches' opencv python

【讨论】:

以上是关于如何从 OpenCV Python 中的特征匹配中获取像素坐标的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV探索之路(二十三):特征检测和特征匹配方法汇总

使用 ORB python opencv 匹配特征

OpenCV-Python教程:41.特征匹配

OpenCV中的特征匹配+单应性以查找对象

opencv 如何检测特定形状的物体

从特征匹配/单应性中过滤掉误报——OpenCV