Да, с этого момента можно продолжить. Вы получите местоположения каждого из них, первый массив - ось y
, а второй массив - ось x
. Эта позиция является верхним левым углом объекта.
Здесь может возникнуть проблема в том, что шаблоны имеют разные размеры ... поэтому они могут перекрываться с другими частями изображения, чего нет в исходном изображении, и я не знаю, является ли это проблемой. Поэтому вам, возможно, придется убедиться, что все они одинаково большие или что у них достаточно места, если это проблема. Это можно решить, например, масштабируя изображения одинакового размера.
В любом случае, вы можете добиться замены следующим образом:
import cv2
import numpy as np
# load the data
img = cv2.imread('scene.jpg')
blueTri = cv2.imread('blueTri.jpg')
blueSq = cv2.imread('blueSq.jpg')
bgColor = (255,255,255)
# find the matching rectangles
res = cv2.matchTemplate(img, blueSq, cv2.TM_CCOEFF_NORMED)
threshold = 0.98 # I used a higher threshold, because it was giving several "good" locations that are next to each other
loc = np.where (res >= threshold)
# process the positions
for i in range(len(loc[0])):
# it is given as (y,x)
pos = (loc[0][i], loc[1][i])
# delete the blue squares
img[pos[0]:pos[0]+blueSq.shape[0] , pos[1]:pos[1]+blueSq.shape[1] ] = bgColor
# put the new blue triangle
img[pos[0]:pos[0]+blueTri.shape[0] , pos[1]:pos[1]+blueTri.shape[1] ] = blueTri
cv2.imshow("Frame", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
А вот результат от синих квадратов до синих треугольников:
И для обоих изменений, как в вашем примере:
Если размеры двух шаблонов равны (т. Е. Изображение, которое вы ищете, и изображение, на которое оно будет заменено), вы можете уменьшить один шаг и изменить цикл for на:
# process the positions
for i in range(len(loc[0])):
# it is given as (y,x)
pos = (loc[0][i], loc[1][i])
# put the new blue triangle
img[pos[0]:pos[0]+blueTri.shape[0] , pos[1]:pos[1]+blueTri.shape[1] ] = blueTri
UPDATE
Чтобы переместить копируемую фигуру, вы можете сдвинуть всю область интереса, в любом случае вы уже удалили старую, так что все будет в порядке. Только не забудьте проверить пределы изображения. Для этого вы можете сделать следующее:
for i in range(len(loc[0])):
posToDelete = (loc[0][i], loc[1][i])
posToAdd = (loc[0][i] -10, loc[1][i]+15) # 10 pixels up and 15 to the right
posToAdd = (max(0, min(posToAdd[0],img.shape[0]-1 -blueTri.shape[0] )) , max(0, min(posToAdd[1],img.shape[1]-1-blueTri.shape[1]))) # sanity check to make sure it is inside the borders
img[posToDelete[0]:posToDelete[0]+blueSq.shape[0] , posToDelete[1]:posToDelete[1]+blueSq.shape[1] ] = bgColor
img[posToAdd[0]:posToAdd[0]+blueTri.shape[0] , posToAdd[1]:posToAdd[1]+blueTri.shape[1] ] = blueTri