如何从 OpenCV 中的特征匹配中获取像素坐标 Python
How to get pixel coordinates from Feature Matching in OpenCV Python
我需要获取特征匹配器在提供的代码中选择的像素的 x
和 y
坐标列表。我正在使用 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)
我们知道您的关键点存储在 kp1
和 kp2
中,它们分别是第一张和第二张图像的特征匹配列表。在 cv2.ORB
视角中,特征描述符是二维矩阵,其中每一行都是在第一张和第二张图像中检测到的关键点。
在你的情况下,因为你正在使用 cv2.BFMatch
、matches
returns 一个 cv2.DMatch
对象的列表,其中每个对象包含多个成员,其中有两个重要成员:
queryIdx
- 匹配 的kp1
兴趣点矩阵的索引或行
trainIdx
- 匹配 的kp2
兴趣点矩阵的索引或行
因此,queryIdx
和 trainIdx
告诉您第一个图像和第二个图像之间哪些 ORB 特征匹配。您将使用这些索引到 kp1
和 kp2
并获得 pt
成员,这是一个 (x,y)
坐标的元组,用于确定匹配项的实际空间坐标。
您所要做的就是遍历 matches
中的每个 cv2.DMatch
对象,附加到 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
中相应位置匹配的特征点的空间坐标。换句话说,list_kp1
的元素i
包含img1
的特征点与list_kp2
的img2
对应的特征点的空间坐标空间坐标在元素 i
中。
作为次要旁注,我在为 drawMatches
编写解决方法时使用了这个概念,因为对于 OpenCV 2.4.x,C++ 函数的 Python 包装器不存在, 所以我利用上面的概念来定位两幅图像之间匹配特征的空间坐标来编写自己的实现。
喜欢就去看看吧!
module' object has no attribute 'drawMatches' opencv python
我需要获取特征匹配器在提供的代码中选择的像素的 x
和 y
坐标列表。我正在使用 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)
我们知道您的关键点存储在 kp1
和 kp2
中,它们分别是第一张和第二张图像的特征匹配列表。在 cv2.ORB
视角中,特征描述符是二维矩阵,其中每一行都是在第一张和第二张图像中检测到的关键点。
在你的情况下,因为你正在使用 cv2.BFMatch
、matches
returns 一个 cv2.DMatch
对象的列表,其中每个对象包含多个成员,其中有两个重要成员:
queryIdx
- 匹配 的trainIdx
- 匹配 的
kp1
兴趣点矩阵的索引或行
kp2
兴趣点矩阵的索引或行
因此,queryIdx
和 trainIdx
告诉您第一个图像和第二个图像之间哪些 ORB 特征匹配。您将使用这些索引到 kp1
和 kp2
并获得 pt
成员,这是一个 (x,y)
坐标的元组,用于确定匹配项的实际空间坐标。
您所要做的就是遍历 matches
中的每个 cv2.DMatch
对象,附加到 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
中相应位置匹配的特征点的空间坐标。换句话说,list_kp1
的元素i
包含img1
的特征点与list_kp2
的img2
对应的特征点的空间坐标空间坐标在元素 i
中。
作为次要旁注,我在为 drawMatches
编写解决方法时使用了这个概念,因为对于 OpenCV 2.4.x,C++ 函数的 Python 包装器不存在, 所以我利用上面的概念来定位两幅图像之间匹配特征的空间坐标来编写自己的实现。
喜欢就去看看吧!
module' object has no attribute 'drawMatches' opencv python