模板匹配

1.介绍

模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别成都,这个差别程度的计算方法在opencv中有6种,然后将每次计算的结果放在一个矩阵里,作为输出结果。接入原图形式A x B大小,而模板式a x b大小,则输出结果的矩阵式(A-a+1) x (B-b+1)

2.函数原型:

result = cv2.matchTemplate(image, template, method, mask=None)

3.参数说明

  1. image:输入的源图像(通常为灰度图),尺寸必须大于模板图像
  2. template:用于匹配的模板图像(通常为灰度图)
  3. method:匹配方法,指定计算相似度的算法
  4. mask:可选参数,模板的掩码,仅在特定匹配方法中使用

4. method类型

TM_SQDIFF:计算平方不同,计算出来的值越小越相关

TM_CCORR:计算相关性,计算出来的值越大越相关

TM_CCEFF:计算相关系数,计算出来的值越大越相关

TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近于0,越相关

TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近于1,越相关

TM_SQDIFF_NORMED:计算归一化相关系数,计算出来的值越接近于1,越相关

其中,归一化的方法(带 NORMED 后缀)通常更推荐使用,因为它们对亮度变化不敏感。

5.返回值

result是一个单通道的灰度图,其中每个像素值表示对应位置的匹配程度,其尺寸为:

  • 宽度:image.shape[1] - template.shape[1] + 1
  • 高度:image.shape[0] - template.shape[0] + 1
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像(灰度模式)
img = cv2.imread(r'C:\learn\MarkDown\anconda\lena.png', 0)
template = cv2.imread(r'C:\learn\MarkDown\anconda\template.png', 0)

# 获取模板尺寸,将前两个值赋值给h和w
h, w = template.shape[:2]

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:
    # 拷贝图像
    img2 = img.copy()
    # 匹配方法的真值 method = eval(meth) 这行代码的作用是将字符串形式的变量名转换为实际的变量(或常量)
    method = eval(meth)
    # 进行模板匹配
    res = cv2.matchTemplate(img, template, method)

    # 找到最佳匹配位置
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

    # 如果式平方差匹配TM_SQDIFF或归一化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, 255, 2)
	
    plt.subplot(121),plt.imshow(res,cmap='gray')
    plt.xticks([]),plt.yticks([]) #隐藏掉坐标轴
    plt.subplot(122),plt.imshow(img2,cmap='gray')
    plt.xticks([]),plt.yticks([])
    plt.suptitle(meth)
    plt.show()
    

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.多模板匹配

import cv2
import numpy as np

# 读取彩色图像
img_rgb = cv2.imread(r'C:\learn\MarkDown\anconda\templatemulExample.png')
# 转换为灰度图,用于模板匹配
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

# 读取模板图像(灰度模式)
template = cv2.imread(r'C:\learn\MarkDown\anconda\templateMulti.png', 0)
# 获取模板的高度和宽度
h, w = template.shape[:2]

# 执行模板匹配(使用归一化相关系数方法)
# 注意:正确的常量是TM_CCOEFF_NORMED(包含两个C)
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)

# 设置匹配阈值(只保留匹配度大于0.8的区域)
threshold = 0.8  # 修正变量名拼写错误

# 找到所有匹配值大于阈值的位置
# np.where返回的是(y, x)形式的坐标,需要转换为(x, y)
loc = np.where(res >= threshold)

# 遍历所有匹配位置并绘制矩形
for pt in zip(*loc[::-1]):  # loc[::-1]将(y, x)转换为(x, y)
    # 计算矩形右下角坐标
    bottom_right = (pt[0] + w, pt[1] + h)
    # 在彩色图像上绘制红色矩形(BGR格式,(0,0,255)表示红色)
    cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)

# 显示结果图像
cv2.imshow('Matching Results', img_rgb)
# 等待用户按键(注意:正确的函数名是waitKey,K大写)
cv2.waitKey(0)
# 关闭所有窗口
cv2.destroyAllWindows()

在这里插入图片描述

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐