05-模板匹配多个物体

需求场景

如果如果一个物体在图像中多次出现,则可使用matchTemplate进行模板匹配。如下,在一张地图中根据模板查找金币并定位其位置。

  • 金币mario_src.jpg

coin

  • 地图mario_coin_template.jpg

map

实现步骤

  1. 初始化图片
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")
  1. 执行匹配并过滤出坐标
# 执行匹配
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]))
  1. 在图片中绘制矩形框
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)
  1. 展示图片
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()

输出结果:

dst