[英]Python, OpenCV to find and overlay/replace portions of an image
需要找到并用其他图像替换图像中的某些部分。
原始图像如下所示。 我想查找和替换:
blue squares to blue triangles
orange squares to orange octagons
图像文件如下:
original.jpg, blue square.jpg, orange square.jpg, blue triangle.jpg, orange octagon.jpg
使用 cv2,我可以找到目标图像的位置。
import cv2
import numpy as np
img_original = cv2.imread("C:\\original.jpg")
img_to_replace_0 = cv2.imread("C:\\blue square.jpg")
img_to_replace_1 = cv2.imread("C:\\orange square.jpg")
img_overlay_0 = cv2.imread("C:\\blue triangle.jpg")
img_overlay_1 = cv2.imread("C:\\orange octagon.jpg")
res_0 = cv2.matchTemplate(img_original, img_to_replace_0, cv2.TM_CCOEFF_NORMED)
res_1 = cv2.matchTemplate(img_original, img_to_replace_1, cv2.TM_CCOEFF_NORMED)
threshold = 0.80
loc_0 = np.where (res_0 >= threshold)
loc_1 = np.where (res_1 >= threshold)
bl_0 = list(loc_0)
bl_1 = list(loc_1)
print bl_0
print bl_1
输出是:
[array([106, 294, 477]), array([17, 18, 21])]
[array([ 22, 210, 393]), array([16, 17, 20])]
进一步进行的最佳方法是什么? CV2 是这种情况下的最佳工具吗? 谢谢你。
是的,可以从这一点继续。 您将获得每个的位置,第一个数组是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
要移动您正在复制的形状,您可以移动整个 ROI,无论如何您已经删除了旧的,这样就可以了。 只是不要忘记检查图像的限制。 为此,您可以执行以下操作:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.