(纯新手教学)计算机视觉(opencv)实战十四——模板与多个对象匹配

发布于:2025-09-12 ⋅ 阅读:(22) ⋅ 点赞:(0)

图片旋转、图片镜像相关教学:
(纯新手教学)计算机视觉(opencv)实战十三——图片旋转、图片镜像 的几种常用方法-CSDN博客https://blog.csdn.net/2302_78022640/article/details/151356600?spm=1011.2415.3001.5331


模板与多个对象匹配

在计算机视觉中,模板匹配(Template Matching)是一种常见的图像处理方法,能够在大图像中寻找与小模板相似的区域。很多时候,模板在目标图像中可能不止出现一次,并且还可能存在旋转的情况。因此,模板与多个对象的匹配技术就显得非常重要。

下面的代码演示了如何使用 OpenCV 进行模板匹配,并支持在目标图像中同时查找多个方向的模板对象。


 核心函数:cv2.matchTemplate

OpenCV 提供了 cv2.matchTemplate 函数来实现模板匹配。

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

参数说明:

  • image:待搜索的图像(通常比模板大)。

  • templ:模板图像,需要在大图中被搜索的目标。

  • method:匹配方法,用来衡量相似度。

  • result:存放匹配结果的矩阵,一般不用手动传入,函数会自动生成。

  • mask:掩膜,可选参数,某些方法不支持。


常见匹配方法

模板匹配的效果依赖于所选择的计算方式。OpenCV 提供了六种主要方法:

  1. TM_SQDIFF(平方差匹配法)

    • 使用平方差衡量误差。

    • 匹配越好,结果值越小。

  2. TM_CCORR(相关匹配法)

    • 采用乘法运算,计算图像与模板的相关性。

    • 数值越大表示匹配程度越高。

  3. TM_CCOEFF(相关系数匹配法)

    • 通过相关系数计算相似度,排除了亮度影响。

    • 数值越大说明匹配效果越好。

  4. TM_SQDIFF_NORMED(归一化平方差匹配法)

    • 与 TM_SQDIFF 类似,但结果被归一化。

    • 匹配越好,值越小。

  5. TM_CCORR_NORMED(归一化相关匹配法)

    • 在 TM_CCORR 的基础上进行归一化,结果范围更稳定。

    • 数值越大,匹配越好。

  6. TM_CCOEFF_NORMED(归一化相关系数匹配法)

    • 在 TM_CCOEFF 的基础上进行归一化,最常用的一种方法。

    • 结果范围通常在 -1 到 1 之间,越接近 1 匹配越好。


图片准备:

arrow.jpg

arrows.jpg

运行结果图:

代码解析

import cv2
import numpy as np

img_rgb = cv2.imread('arrows.jpg')
cv2.imshow('img_gray', img_rgb)
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

template1=cv2.imread('./arrow.jpg', flags=0)
# 旋转 90 度,k=-1 表示顺时针旋转 90 度
template2 = np.rot90(template1, k=-1)
# 旋转 90 度,k=1 表示逆时针旋转 90 度
template3 = np.rot90(template1, k=1)
template4 = np.rot90(template1, k=2)
cv2.imshow('template1', template1)
cv2.imshow('template2', template2)
cv2.imshow('template3', template3)
cv2.imshow('template4', template4)
cv2.waitKey(0)

templates=[template1,template2,template3,template4]

for template in templates:
    h, w = template.shape[:2]

    # 使用模板匹配方法 cv2.matchTemplate 进行模板匹配
    res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
    threshold = 0.9  # 设定匹配阈值

    # 获取匹配结果中所有符合阈值的点的坐标
    loc = np.where(res >= threshold)  # 符合条件的行,符合条件的列
    # print(loc)

    # 遍历所有匹配点
    for pt in zip(*loc[::-1]):
        # 在原图上绘制匹配区域的矩形框
        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), color=(0, 0, 255), thickness=1)

cv2.imshow('result', img_rgb)
cv2.waitKey(0)

核心步骤讲解

  1. 读取图像并灰度化

    • 使用 cv2.imread 读取原始图像 arrows.jpg,并转换为灰度图。

    • 灰度图可以减少计算量,同时保留了模板匹配所需的主要信息。

  2. 加载模板并进行旋转

    • 模板 arrow.jpg 作为基本形状。

    • 使用 np.rot90 对模板进行旋转,生成 4 个方向的模板(0°、90°、180°、270°)。

    • 这样就能应对目标图像中箭头方向不一致的情况。

  3. 模板匹配

    • cv2.matchTemplate 用于计算模板与目标图像各个位置的匹配程度。

    • 选择 cv2.TM_CCOEFF_NORMED 方法,该方法会输出归一化相关系数,值越接近 1 表示越相似。

  4. 匹配阈值设定

    • 设置 threshold = 0.9,即相似度大于等于 0.9 的区域才认为是有效匹配。

    • 阈值过低可能引入误检,过高可能漏检。

  5. 定位与绘制

    • np.where(res >= threshold) 找到所有符合条件的点。

    • 使用 cv2.rectangle 在原图 img_rgb 上绘制矩形框,标记出匹配区域。

  6. 结果展示

    • 使用 cv2.imshow 显示最终带有标记的图像。


应用场景

  1. 目标检测
    在工厂生产线上检测零件是否存在、方向是否正确。

  2. 游戏自动化
    在屏幕截图中查找某个按钮或图标的位置,实现自动点击。

  3. 文档处理
    在扫描件中查找特定的标志或符号。

  4. 视频监控
    在实时视频中检测特定物体的出现与方向。


方法优缺点

  • 优点

    • 实现简单,代码量少。

    • 适合已知模板的精确匹配任务。

    • 可以通过旋转模板来解决方向差异。

  • 缺点

    • 对尺度变化不敏感(如果模板大小与目标图像中对象大小不同,效果不好)。

    • 对光照、噪声等变化敏感。

    • 计算效率在大规模匹配时较低。


总结

通过这段代码,可以看到如何使用 OpenCV 的模板匹配方法,结合旋转操作,在图像中查找多个方向的相同目标对象。该方法在简单场景下效果显著,尤其适合对象外形固定、尺寸不变的任务。


网站公告

今日签到

点亮在社区的每一天
去签到