Совмещение контура или нарисованного (png) контура на другом изображении - PullRequest
0 голосов
/ 04 августа 2020

Допустим, я нашел контур на изображении. Как лучше всего найти положение этого контура на изображении 2?

Я вижу два варианта: Либо я рисую контур белой линией и сопоставляю это изображение на изображении 2, либо я каким-то образом (это даже возможно?) соответствовать контуру на изображении 2.

Содержимое внутри контура полностью случайное, но контур из изображения 1, нарисованный белой линией 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

Любые советы по улучшению были бы очень признательны!

1 Ответ

1 голос
/ 05 августа 2020

Вы можете использовать matchTemplate в Python / OpenCV с изображением маски, чтобы игнорировать области шаблона. Итак, если у вас есть прозрачный шаблон, извлеките альфа-канал и используйте его в качестве маски, используя каналы BGR шаблона в качестве изображения шаблона в matchTemplate. См.

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

cv2.matchTemplate находит неправильный шаблон в изображении

Как сопоставить шаблон с простая 2D-форма в OpenCV?

...