我不理解的是,如何从matchTemplate函数的输出中提取匹配位置,并且这些信息是如何存储的。该结果将返回图像中每个像素与模板的相似度,例如与模板左上角像素的相似度。
loc =numpy.where(result >= 0.7)
我们将使用上述方法来筛选可能性。我们将获取图像中可能性大于0.7的像素与模板顶角的x坐标和y坐标。
现在我们获取了与左上角模板相似度可能大于或等于0.7的图像位置。
在我们的示例输出中,可以看到我们可以根据阈值获得许多匹配点。我们需要循环它们以找到每个位置。
由于我们知道loc变量是一个元组,包含两个NumPy数组(Y坐标NumPy数组和X坐标NumPy数组),我们需要解包元组并反转数组的顺序以获取模板的实际位置,如下所示。
“基本上我想做的是将几个模板与一张图像匹配,然后确定哪个模板最符合每个位置(在所有应用的模板中具有最大匹配值)。”
问题是,每个结果的形状不同,因为它取决于模板的高度和宽度。
我们可以轻松地使用cv2.resize方法使所有模板具有相同的形状(可以近似为所有模板)。
'''
my original template shapes
img (1256, 1300)
tempate (215, 223)
tempate (217, 204)
tempate (207, 203)
width =220
height = 225
temp = cv2.resize(temp,(width,height),cv2.INTER_CUBIC)
这个使我们的结果与下面的形状相同。
res = cv2.matchTemplate(gray, temp,cv2.TM_CCOEFF_NORMED)
print(res.shape)
我的方法
我找到了包含所有结果的最大可能数组。所有的结果都被添加到结果列表中。
maximum_values_array = np.maximum(*results)
我找到了该位置具有最大值的res。
maximum_value_contains_array =np.array(results).argmax(axis=0)
我遍历每一个大于零的可能值(阈值>0.7),根据具有最大值的数组选择颜色。
for i in range(len(maximum_values_array)):
for j in range(len(maximum_values_array[i])):
if maximum_values_array[i][j]>0:
colour = colours[maximum_value_contains_array[i][j]]
top_lect = (j,i)
bottom_right = (j+width, i+height)
cv2.rectangle(img,top_lect,bottom_right, colour, 2)
完整的 Python 代码
import cv2
import numpy as np
img = cv2.imread('test.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
templates = [cv2.imread('blue_temp.jpg', 0), cv2.imread('yellow_temp.jpg', 0), cv2.imread('red_temp.jpg', 0)]
colours =[(255,0,0), (0,255,0),(0,0,255)]
results =[]
for temp in templates:
print(temp.shape)
width =205
height = 205
res = cv2.matchTemplate(gray, temp,cv2.TM_CCOEFF_NORMED)
res[res<0.9] =0
results.append(res)
maximum_values_array = np.maximum(*results)
maximum_value_contains_array =np.array(results).argmax(axis=0)
print(maximum_values_array.shape)
print(maximum_value_contains_array.shape)
for i in range(len(maximum_values_array)):
for j in range(len(maximum_values_array[i])):
if maximum_values_array[i][j]>0:
print(maximum_values_array[i][j])
colour = colours[maximum_value_contains_array[i][j]]
top_lect = (j,i)
bottom_right = (j+width, i+height)
cv2.rectangle(img,top_lect,bottom_right, colour, 2)
cv2_imshow(img)
cv2.imwrite('output.png', img)