模板匹配是一个寻找大图像中目标位置的方法。OpenCV提供了函数 cv2.matchTemplate() 函数,通过在输入图像上滑动模板,将目标与滑动处的图像 patch 进行匹配,OpenCV中实现了很多种不同的方法,返回的是一个结果图像,结果图像的每个像素代表的滑动位置的匹配值。如果输入图像是 W ∗ H W*H W∗H, 模板图像大小是 w ∗ h w*h w∗h, 那么结果图像的大小为 ( W − w + 1 ) ∗ ( H − h + 1 ) (W-w+1)*(H-h+1) (W−w+1)∗(H−h+1)。最终可以使用 cv2.minMaxLoc函数获得匹配结果最大值或最小值的位置。
如果使用 cv2.TM_SQDIFF 作为比较方法,最小值代表越匹配。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread("assets/messi5.jpg", 0)
img2 = img.copy()
template = cv2.imread("assets/messi_face.png", 0)
w, h = template.shape
methods = ["cv2.TM_CCOEFF", "cv2.TM_CCOEFF_NORMED",
"cv2.TM_CCORR", "cv2.TM_CCORR_NORMED",
"cv2.TM_SQDIFF", "cv2.TM_SQDIFF_NORMED"]
for meth in methods:
img = img2.copy()
method = eval(meth)
res = cv2.matchTemplate(img2, templ=template, method=method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# 如果用的是 cv2.TM_SQDIFF 或 cv2.TM_SQDIFF_NORMED, 则用最小值
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(img, top_left, bottom_right, color=255, thickness=2)
# cv2.imshow('Match Res', res)
# cv2.imshow('Det Res', img)
# cv2.waitKey(0)
plt.subplot(121), plt.imshow(res, cmap='gray')
plt.title('Match Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img, cmap='gray')
plt.title('Detect Point'), plt.xticks([]), plt.yticks([])
plt.suptitle(meth)
plt.savefig(meth+'.png', bbox_inches='tight')
plt.show()
# cv2.destroyAllWindows()
import cv2
import numpy
from matplotlib import pyplot as plt
img = cv2.imread("assets/coin.png")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template = cv2.imread("assets/coin_template.png", 0)
w, h = template.shape
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):
cv2.rectangle(img, pt, (pt[0]+w, pt[1]+h), (0, 255, 0), 2)
cv2.imshow("result", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.matchTemplate( image, templ, method[, result[, mask]] ) -> result
Compares a template against overlapped image regions.
- image: 需要寻找目标的图像
- templ: 模板(或目标)
- method: 匹配方法
- result: 32位单通道浮点图像,
- mask: 大小和 templ 一致,通道数一致或为单通道。
cv2.minMaxLoc( src[, mask] ) -> minVal, maxVal, minLoc, maxLoc
寻找全局最大最小值以及位置
不适合多通道使用,如果确实要在多通道上使用,可以改变形状,或者分离通道等操作
- src: 单通道图像或数据
- minVal: 最小值
- maxVal: 最大值
- minLoc: 最小值的位置
- maxLoc: 最大值的位置
- mask: 掩码