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?
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.
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.
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). https://i.sstatic.net/4IxOp.jpg
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. 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://i.sstatic.net/zQxnp.jpg
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. 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. See
https://docs.opencv.org/4.1.1/df/dfb/group__imgproc__object.html#ga586ebfb0a7fb604b35a23d85391329be