【问题标题】:Matching contour or drawn (png) contour on another image在另一个图像上匹配轮廓或绘制 (png) 轮廓
【发布时间】:2020-11-24 22:57:45
【问题描述】:

假设我在图像上找到了轮廓。在图像 2 上找到此轮廓位置的最佳方法是什么?

我看到两个选项:要么我用白线绘制轮廓并匹配图像 2 上的图像,要么我以某种方式(这甚至可能吗?)直接匹配图像 2 上的轮廓。

轮廓内的内容是完全随机的,但假设我可以模板匹配具有透明度的图像,则使用白色 1px 线绘制的图像 1 的轮廓将是完全匹配的。

以下是找到、绘制和保存的轮廓的示例图像(图像 1)和我需要在其中定位图像 1 的图像(图像 2)。 https://imgur.com/a/MNQ6aNr

无需先绘制和保存即可找到轮廓,但我认为匹配绘制的轮廓更直接。

谢谢

编辑:

这是我的完整代码。它需要一个 full_image 和一个片段,它将在完整图像上匹配。最后它会导出一些结果。

full_image = cv2.imread('puzzle_1.jpg')    
piece = cv2.imread('piece_1.png', cv2.IMREAD_UNCHANGED)
partial_image = cv2.cvtColor(piece,cv2.COLOR_BGR2GRAY)

contours, hierarchy = cv2.findContours(partial_image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
   
template = np.zeros((55, 55, 4), dtype=np.uint8)

cv2.drawContours(template, contours, -1, (255, 255, 255, 255),1)
hh, ww = template.shape[:2]

puzzleP = template[:,:,0:3]
alpha = template[:,:,3]
alpha = cv2.merge([alpha,alpha,alpha])

correlation = cv2.matchTemplate(full_image, puzzleP, cv2.TM_CCORR_NORMED, mask=alpha)

threshhold = 0.98
loc = np.where(correlation >= threshhold)

result = full_image.copy()
for pt in zip(*loc[::-1]):
    cv2.rectangle(result, pt, (pt[0]+ww, pt[1]+hh), (0,0,255), 1)
    print(pt)
    
cv2.imwrite('puzzle_piece.png', puzzleP)
cv2.imwrite('full_image_alpha.png', alpha)
cv2.imwrite('full_image_matches.jpg', result)  

这是一个运行良好的结果和一个无效的结果 https://imgur.com/a/ZYyw7tU

任何关于改进的提示将不胜感激!

【问题讨论】:

  • 对不起,我不明白你的问题。模板轮廓在第二张图像中没有匹配的形状。那么你怎么知道把它放在哪里呢?如果您有放置它的坐标。您可以将轮廓保存为黑色图像上的白线,然后将其覆盖到第二张图像上某个所需的偏移坐标处。请进一步澄清您的问题。
  • 我会尝试进一步澄清。我实际上只需要在图像 2 上找到图像 1 的位置,而不管图像 2 的形状内有什么内容。我在这里可能会混淆术语。换句话说:在图像 1 上绘制的线存在于图像 2 中,但在图像 1 上,这条线内的内容是透明的,因为它在图像 2 的线上有一些图片。我如何找到边界的位置图 2 上这条白线(绘制轮廓)的框?
  • 我不想将它画在任何特定的位置(我已经在图 1 上画了它)。我只是好奇是否更容易匹配图像 2 上的绘制轮廓(图像 1)。或者是否有一种方法可以跳过绘制并保存它,以便在图像 2 上找到边界框。
  • 您可以使用带有遮罩图像的 matchTemplate 来忽略模板的区域。因此,如果您有一个透明模板,则提取 alpha 通道并将其用作蒙版,使用模板 BGR 通道作为 matchTemplate 中的模板图像。请参阅docs.opencv.org/4.1.1/df/dfb/…stackoverflow.com/questions/61779288/…stackoverflow.com/questions/59759374/…
  • 谢谢,我试试看!

标签: python opencv computer-vision template-matching


【解决方案1】:

您可以在 Python/OpenCV 中使用带有掩码图像的 matchTemplate 来忽略模板的区域。因此,如果您有一个透明模板,则提取 alpha 通道并将其用作蒙版,使用模板 BGR 通道作为 matchTemplate 中的模板图像。见

https://docs.opencv.org/4.1.1/df/dfb/group__imgproc__object.html#ga586ebfb0a7fb604b35a23d85391329be

cv2.matchTemplate finds wrong template in image

How to template match a simple 2D shape in OpenCV?

【讨论】:

  • 我已经用关于优化我的解决方案的信息编辑了我的问题。写一个全新的问题可能是一个更好的主意?
猜你喜欢
  • 2011-12-13
  • 1970-01-01
  • 2012-01-04
  • 2021-09-07
  • 2019-02-12
  • 2021-01-05
  • 1970-01-01
  • 2014-03-20
  • 1970-01-01
相关资源
最近更新 更多