【问题标题】:Finding matching data point within two images using Python使用 Python 在两个图像中查找匹配的数据点
【发布时间】:2021-06-08 05:34:00
【问题描述】:

我有两张图片,即图 1 和图 2。两者均取自同一来源但未对齐。任务是在这两个图像中找到共同的数据点,并在两个图像中匹配的数据点之间画线。我看这个图应该像图4。

到目前为止,我使用过OpenCV并编写了以下代码:

import cv2 
import matplotlib.pyplot as plt

img_file1= "Fig_1.png"
img_file2= "Fig_2.png"
img1= cv2.imread(img_file1)
img2= cv2.imread(img_file2)
    
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

figure, ax = plt.subplots(1, 2, figsize=(16, 8))

ax[0].imshow(img1, cmap='gray')
ax[1].imshow(img2, cmap='gray')

#sift
sift = cv2.xfeatures2d.SIFT_create()

keypoints_1, descriptors_1 = sift.detectAndCompute(img1,None)
keypoints_2, descriptors_2 = sift.detectAndCompute(img2,None)

#feature matching
bf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True)

matches = bf.match(descriptors_1,descriptors_2)
matches = sorted(matches, key = lambda x:x.distance)

img3 = cv2.drawMatches(img1, keypoints_1, img2, keypoints_2, matches[:50], img2, flags=2)
plt.imshow(img3),plt.show()

这给出了意想不到的结果,见图 4。加上看起来相当混乱和不清楚。

谁能帮助我如何做到这一点?提前致谢。

图一

图 2

img3

图3

【问题讨论】:

  • 图3代表什么?上面代码的输出?
  • 是的,图 3 代表我的代码 (img3) 的输出。
  • 我的猜测是,由于要检测的特征只是白色圆圈,特征检测器检测到圆圈,并且由于图像充满了相似的特征(即)白色圆圈,匹配器无法匹配适当的。
  • 尝试使用不同的示例运行代码,例如 opencv 文档 (docs.opencv.org/master/dc/dc3/tutorial_py_matcher.html) 中显示的示例,并检查是否得到类似的结果。
  • 试过但得到了类似的结果。 fig3 好像是把图片加在一起了,怎么才能让这两者之间的距离,让我可以清楚的看到哪些数据点属于哪一个呢?

标签: python opencv image-processing computer-vision sift


【解决方案1】:

这种转变似乎纯粹是平移。尝试通过归一化灰度相关进行模板匹配。

【讨论】:

  • 怎么做。可以举个例子吗?
  • @Ravi:在文档中搜索模板匹配。
  • @YvesDaoust 他试图找到两个图像之间的共同数据点并匹配它们。这种情况下的模板应该是什么?
  • @Kishore:整张图片减去翻译余量。
【解决方案2】:

基本上,这在我看来是一个注册问题(图像需要注册)。

你可以这样做:

  1. connected components analysis查找点的位置
  2. 计算register the two images 所需的班次。在这里,您的图像似乎只被翻译,因此基于互相关的简单配准就足够了。

from skimage.registration import phase_cross_correlation
from skimage.io import imread
from skimage.measure import label, regionprops
from skimage.filters import threshold_otsu

from matplotlib.pyplot import imshow, plot, figure
import numpy as np


# Load images
img_a = imread("671OL.jpg", as_gray=True)
img_b = imread("zpevD.jpg", as_gray=True)

# apply threshold
th_img_a = img_a > threshold_otsu(img_a)
th_img_b = img_b > threshold_otsu(img_b)

# measure connected component
img_lable = label(th_img_a)
r_props = regionprops(img_lable)

figure(figsize=(15,7))
rows, cols = img_b.shape

# calculate the registration (shift) of the two images
flow = phase_cross_correlation(th_img_a, th_img_b)

# stack the images and trace the segments that connect the points
d=10
# a vertical white bar between the two pictures
vbar=np.ones((rows,d))
xshift = cols+d
dy,dx = flow[0]
dx=dx + xshift
imshow(np.hstack([img_a, vbar, img_b]), cmap='gray')
for rp in r_props:
    y0,x0 = rp.centroid
    x1 = x0 + dx
    y1 = y0 - dy
    if y1<rows and x1 < 2*cols + d:
        # filter out points that are not in img_b
        plot([x0,x1],[y0,y1], '--', alpha=0.5)

【讨论】:

  • 在运行您的代码时,我收到此错误 'cannot import name 'optical_flow_ilk' from 'skimage.registration (C:\Users\rp603\Anaconda3\lib\site-packages\skimage\registration_init_.py)''
  • 删除它,确实不需要。我删除了无用的导入
  • 如果,我可以找到每个图像的每个数据点的坐标,然后根据坐标,尝试找到匹配的数据点。但不知道该怎么做。
  • 你是对的,我认为这个脚本完全按照你说的做:标签函数在一张图像中“找到点”,脚本中的最后一个循环计算另一张图像中的坐标(现在堆叠在右侧)
  • 我运行了代码。发现以下问题。 1. 最终的图很乱,几乎无法识别哪个数据点连接到其他图像数据点。是否可以让这张图片带有距离和颜色,以便我可以清楚地看到?
猜你喜欢
  • 2019-01-04
  • 2020-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 2016-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多