简体   繁体   English

在另一个图像上匹配轮廓或绘制 (png) 轮廓

[英]Matching contour or drawn (png) contour on another image

Let's say i have found a contour on an image.假设我在图像上找到了轮廓。 What is the best approach to finding the position of this contour on image 2?在图像 2 上找到此轮廓的 position 的最佳方法是什么?

I see two options: Either i draw the contour with a white line and match that image on image 2 or i somehow (is this even possible?) match the contour on image 2 directly.我看到两个选项:要么我用白线绘制轮廓并匹配图像 2 上的图像,要么我以某种方式(这甚至可能吗?)直接匹配图像 2 上的轮廓。

The contents within the contour is completely random, but the contour from image 1 drawn with a white 1px line would be an exact match, assuming i could template match an image with transparency.轮廓内的内容是完全随机的,但是假设我可以模板匹配具有透明度的图像,则使用白色 1px 线绘制的图像 1 的轮廓将是完全匹配的。

Here are example images of a found, drawn and saved contour (image 1) and an image in which i need to locate image 1 (image 2).以下是找到、绘制和保存的轮廓的示例图像(图像 1)和我需要在其中定位图像 1 的图像(图像 2)。 https://imgur.com/a/MNQ6aNr https://imgur.com/a/MNQ6aNr

Finding the contour without having to draw and save it first would be preferred, but i assume matching the drawn contour is more straight forward.无需先绘制和保存就可以找到轮廓,但我认为匹配绘制的轮廓更直接。

Thanks谢谢

Edit:编辑:

This is my full code.这是我的完整代码。 It takes a full_image and a piece, which it will match on the full image.它需要一个 full_image 和一个片段,它将在完整图像上匹配。 Lastly it exports some results.最后它导出一些结果。

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)  

Here is a well working result and an invalid result https://imgur.com/a/ZYyw7tU这是一个运行良好的结果和一个无效的结果https://imgur.com/a/ZYyw7tU

Any tips on improvement would be greatly appreciated!任何有关改进的提示将不胜感激!

You can use matchTemplate in Python/OpenCV with a mask image to ignore regions of the template.您可以在 Python/OpenCV 中使用带有掩码图像的 matchTemplate 来忽略模板的区域。 So if you have a transparent template, then extract the alpha channel and use that as a mask using the template BGR channels as the template image in matchTemplate.因此,如果您有一个透明模板,则提取 alpha 通道并将其用作蒙版,使用模板 BGR 通道作为 matchTemplate 中的模板图像。 See

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

cv2.matchTemplate finds wrong template in image cv2.matchTemplate 在图像中找到错误的模板

How to template match a simple 2D shape in OpenCV? 如何模板匹配 OpenCV 中的简单二维形状?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM