05-模板匹配多个物体¶
需求场景¶
如果如果一个物体在图像中多次出现,则可使用matchTemplate
进行模板匹配。如下,在一张地图中根据模板查找金币并定位其位置。
- 金币mario_src.jpg
- 地图mario_coin_template.jpg
实现步骤¶
- 初始化图片
import matplotlib.pyplot as plt
import numpy as np
import cv2
img = cv2.imread("../images/mario_src.jpg")
img_copy = img.copy()
template =cv2.imread("../images/mario_coin_template.jpg")
- 执行匹配并过滤出坐标
# 执行匹配
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
# 设置阈值
threshold = 0.8
loc = np.where(res >= threshold)
# 倒着取出
print(loc[::-1])
output:
(array([ 73, 87, 101, 115, 129, 73, 87, 101, 102, 115, 116, 129, 130,
73, 87, 101, 115, 129, 59, 73, 87, 101, 115, 129, 143, 58,
59, 73, 87, 101, 102, 115, 116, 129, 130, 143, 144, 59, 73,
87, 101, 115, 129, 143, 59, 73, 87, 101, 115, 129, 143]), array([ 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67,
68, 68, 68, 68, 68, 98, 98, 98, 98, 98, 98, 98, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 100, 100,
100, 100, 100, 100, 100, 131, 131, 131, 131, 131, 131, 131]))
- 在图片中绘制矩形框
h, w = template.shape[:2]
# 倒着取出,展开后组合成坐标列表
for point in zip(*loc[::-1]):
cv2.rectangle(img_copy, point, (point[0]+w, point[1]+h), (0,0,255), 2)
- 展示图片
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
template = cv2.cvtColor(template, cv2.COLOR_BGR2RGB)
img_copy = cv2.cvtColor(img_copy, cv2.COLOR_BGR2RGB)
dst = np.hstack((img, img_copy))
plt.subplot(211), plt.imshow(dst)
# 显示标题并隐藏坐标轴
plt.title("Result"), plt.xticks([], plt.yticks([]))
plt.subplot(212), plt.imshow(template)
# 显示标题并隐藏坐标轴
plt.title('Coin'), plt.xticks([], plt.yticks([]))
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果: