OpenCV Python 模板匹配
【目标】
- 利用模板匹配的方法寻找目标
- cv2.matchTemplate(), cv2.minMaxLoc()
【理论】
模板匹配是一个寻找大图像中目标位置的方法。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()
【接口】
- matchTemplate
cv2.matchTemplate(	image, templ, method[, result[, mask]]	) ->	result
Compares a template against overlapped image regions.
- image: 需要寻找目标的图像
- templ: 模板(或目标)
- method: 匹配方法
- result: 32位单通道浮点图像,
- mask: 大小和 templ 一致,通道数一致或为单通道。
- TemplateMatchModes


- minMaxLoc
cv2.minMaxLoc(	src[, mask]	) ->	minVal, maxVal, minLoc, maxLoc
寻找全局最大最小值以及位置
不适合多通道使用,如果确实要在多通道上使用,可以改变形状,或者分离通道等操作
- src: 单通道图像或数据
- minVal: 最小值
- maxVal: 最大值
- minLoc: 最小值的位置
- maxLoc: 最大值的位置
- mask: 掩码
【参考】
- OpenCV 官方文档
![[附源码]计算机毕业设计JAVA校园淘宝节系统](https://img-blog.csdnimg.cn/fb7f1dc558b7448fa6e8fe84a8ffde43.png)






![[附源码]Python计算机毕业设计Django海南琼旅旅游网](https://img-blog.csdnimg.cn/2955a7a77f174cb2a151a42e92316b01.png)











