乐于分享
好东西不私藏

教程 | 如何实现图像模板匹配 by OpenCV

教程 | 如何实现图像模板匹配 by OpenCV
点击上方“i怡心兮”关注我们吧~
摘要:OpenCV提供了一个经过实时优化的计算机视觉库、工具和硬件。它还支持机器学习(ML)和人工智能(AI)的模型执行。本文介绍了如何基于OpenCV实现图像模板匹配。

以下的指导教程基于Windows系统,苹果电脑的MacOS系统类似。

Part.0 模板匹配是什么

图像模板匹配(Template Matching)一位极其死板但又不可或缺的“刻舟求剑”专家。用一句最接地气的话来定义它:模板匹配,就是数字图像世界里的“人肉雷达”和“复读机鉴黄师”。 你扔给它一张小图(模板),它就在大图里像个没感情的扫描仪一样来回溜达,试图找出“和这张小图长得一模一样」的地方。

一、 它是怎么工作的?(“戴着头盔”的地毯式搜索)

计算机是个极其死板的家伙,它不懂什么叫“大概”,什么叫“神似”。它的模板匹配过程,笨拙得让人发笑,主要分为两步:

1. 暴力滑窗(Sliding Window)

想象一下,你有一张很大的寻宝图(原图像),手里拿着一个特定的小拼图块(模板)。计算机做的事,就是把这个小拼图块放在大图的左上角,对齐像素,计算一下两者的差异;然后把它往右移动一个像素,再算一次;移到最右边后,再往下移动一行,继续从左往右算……直到遍历完整个大图。

这就像你戴着一顶只能遮住头顶的遮阳帽,在偌大的操场上找一颗特定的螺丝钉。你必须一步一步地挪动,用帽子盖住每一个可能的位置,低头看一眼,再挪一步。极其费时,但胜在绝对不会漏掉任何一个角落

2. 算账比惨(Similarity Measurement)

每移动一次,计算机就会用预设的“评判标准”给当前这块区域打个分。常见的评分标准有:

  • 平方差匹配(SSD):把两个区域对应像素的差值平方加起来。分数越低,说明越像。(计算机心想:差得越少,分得越清,这账算得明明白白!)

  • 相关系数匹配(CCOEFF):不仅看差值,还看变化趋势。分数越高,说明越像。

这就像两个强迫症在比对DNA,不仅要碱基对上,连螺旋的方向都得完全一致才算数。

最终,计算机把全图所有位置的“分数”列出来,分数最高(或最低,取决于算法)的那个点,就是它认为的“最佳匹配位置”。


二、 这位“福尔摩斯”有多死板?(三大致命弱点)

虽然模板匹配听起来很美好,但它有个致命的缺陷——它是一个“认死理”的直男。 它有三个绝对的“雷区”:

  1. 怕“长胖”或“变瘦”(尺度敏感性)

    如果你的模板是50x50像素,但原图里的目标是100x100像素(缩放),哪怕只是稍微远了一点导致成像变小,计算机也会无情地判定:“不像!不匹配!”它不会像人类一样自动脑补比例。

  2. 怕“扭脖子”(旋转敏感性)

    模板里是个正立的杯子,原图里的杯子如果只是歪了15度,计算机就会一脸懵逼:“这 curvature(曲率)不对啊,不是同一个杯子!”它眼里揉不得半点角度的沙子。

  3. 怕“换滤镜”(光照敏感性)

    模板是在晴天室内拍的(亮度高),原图是在阴天拍的同一个地方(亮度低)。仅仅因为整体像素值都变了,模板匹配就可能直接罢工。

这就像你拿着爱豆十年前的护照照片去机场接机,结果爱豆换了发型、穿了宽松衣服,还晒黑了。模板匹配保准在你眼皮底下走过,你都认不出来,甚至还会报警说遇到了冒名顶替者!


三、 既然这么笨,为什么还要用它?(应用场景)

你可能会问:“这也不能干,那也不行,要它何用?”嘿,在特定的工业场景下,它可是性价比极高的“神器”!

1. 工业流水线上的“质检员”

在电子厂,需要确认电路板上的某个电容是不是被装反了,或者缺焊了。因为流水线上的物品位置、大小、角度都是严格固定的,光照也是恒定不变的。此时,模板匹配一秒钟能扫几百个,又快又准,简直是资本家的福音!只要环境绝对可控,它就是最快、最便宜的“流水线监工”

2. 固定UI界面的“自动化测试猿”

程序员写了个脚本,想在电脑屏幕上自动点击某个软件的“确定”按钮。他只需要截个“确定”按钮的小图,然后用模板匹配在全屏找。因为UI界面通常不会自己缩放旋转,所以百发百中。代替苦逼打工人完成机械的鼠标点击,打工人的福音

3. 简单的“找Logo”或“找图标”

比如在一堆杂乱的文件中,快速定位出所有的PDF图标或者微信的绿色气泡。只要图标本身没有变形变色,模板匹配依然是最轻量级的首选方案。


如果说边缘检测和形态学是图像的“骨科医生”,那么模板匹配就是个“认死理的门卫大爷”。它不懂变通,惧怕旋转、缩放和光照变化,但在环境受控、目标规整的特定场景下,它以其零训练成本、极易上手的优势,成为了无数轻量级自动化项目的首选方案。记住一句话:不要用全能AI的标准去要求一个只想好好“找茬”的算法。 只要把环境固定好,模板匹配绝对是你最忠诚、最勤快的像素打工人!

Part.1 如何实现图像模板匹配
图像模板匹配 = 滑动窗口 + 计算相似度,常用于在大图中找小图、定位目标、圆形 / 零件精准匹配计数等场景,包含 平方差、归一化平方差、相关匹配、归一化相关、相关系数、归一化相关系数 等方法,各方法特点说明如下表所示。
方法
含义
最佳值
特点
TM_SQDIFF
平方差匹配
越小越匹配
简单,受光照影响大
TM_SQDIFF_NORMED
归一化平方差
越小越匹配
稳定、常用
TM_CCORR
相关匹配
越大越匹配
亮度敏感,易误判
TM_CCORR_NORMED
归一化相关
越大越匹配
常用
TM_CCOEFF
相关系数
越大越匹配
抗干扰强
TM_CCOEFF_NORMED
归一化相关系数
越大越匹配
最强、最准、首选!
各种模板匹配方法的代码实现如下:
import cv2import numpy as npimport matplotlib.pyplot as plt# ================== 1. 读取图像 ==================# 大图(在这张图里找模板)img = cv2.imread("image.jpg")# 模板(你要找的小图)template = cv2.imread("template.jpg")# 获取模板宽高h, w = template.shape[:2]# ================== 2. 6种匹配方法 ==================methods = [    ("平方差匹配", cv2.TM_SQDIFF),    ("归一化平方差", cv2.TM_SQDIFF_NORMED),    ("相关匹配", cv2.TM_CCORR),    ("归一化相关", cv2.TM_CCORR_NORMED),    ("相关系数", cv2.TM_CCOEFF),    ("归一化相关系数", cv2.TM_CCOEFF_NORMED)]# 遍历所有方法for name, method in methods:    img_copy = img.copy()    # 执行模板匹配    result = cv2.matchTemplate(img_copy, template, method)    # 获取最值与坐标    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)    # ================== 3. 判断最佳匹配位置 ==================    # 平方差越小越好    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:        top_left = min_loc        similarity = 1 - min_val  # 转成相似度    else:        top_left = max_loc        similarity = max_val     # 直接是相似度    # 右下角坐标    bottom_right = (top_left[0] + w, top_left[1] + h)    # 画矩形    cv2.rectangle(img_copy, top_left, bottom_right, (0,255,0), 2)    # 标注相似度    cv2.putText(img_copy, f"{name}{similarity:.3f}"                (20,50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)    # 显示结果    cv2.imshow(f"{name}", img_copy)cv2.waitKey(0)cv2.destroyAllWindows()
从实际使用经验来看,模板匹配归一化方法永远比非归一化稳定,表中最佳匹配算法:TM_CCOEFF_NORMED(归一化相关系数),输出值范围 0~1,越接近 1 越匹配,而且可用于多目标匹配(设置阈值筛选)。
End 视觉相关资源获取 
机器视觉相关案例及其源代码获取地址:
# 图像模板匹配 相关源码获取地址: https://pan.baidu.com/s/1ic_o7R6Sks2OeFyifCqL1A 公众号私信发送【视觉源码】获取 提取码

点击【i怡心兮】- 右上角找到【

立刻设置为✨星标/置顶 ~ 谢谢