
以下的指导教程基于Windows系统,苹果电脑的MacOS系统类似。
Part.0 模板匹配是什么
图像模板匹配(Template Matching)一位极其死板但又不可或缺的“刻舟求剑”专家。用一句最接地气的话来定义它:模板匹配,就是数字图像世界里的“人肉雷达”和“复读机鉴黄师”。 你扔给它一张小图(模板),它就在大图里像个没感情的扫描仪一样来回溜达,试图找出“和这张小图长得一模一样」的地方。

一、 它是怎么工作的?(“戴着头盔”的地毯式搜索)
计算机是个极其死板的家伙,它不懂什么叫“大概”,什么叫“神似”。它的模板匹配过程,笨拙得让人发笑,主要分为两步:
1. 暴力滑窗(Sliding Window)
想象一下,你有一张很大的寻宝图(原图像),手里拿着一个特定的小拼图块(模板)。计算机做的事,就是把这个小拼图块放在大图的左上角,对齐像素,计算一下两者的差异;然后把它往右移动一个像素,再算一次;移到最右边后,再往下移动一行,继续从左往右算……直到遍历完整个大图。
这就像你戴着一顶只能遮住头顶的遮阳帽,在偌大的操场上找一颗特定的螺丝钉。你必须一步一步地挪动,用帽子盖住每一个可能的位置,低头看一眼,再挪一步。极其费时,但胜在绝对不会漏掉任何一个角落。
2. 算账比惨(Similarity Measurement)
每移动一次,计算机就会用预设的“评判标准”给当前这块区域打个分。常见的评分标准有:
平方差匹配(SSD):把两个区域对应像素的差值平方加起来。分数越低,说明越像。(计算机心想:差得越少,分得越清,这账算得明明白白!)
相关系数匹配(CCOEFF):不仅看差值,还看变化趋势。分数越高,说明越像。
这就像两个强迫症在比对DNA,不仅要碱基对上,连螺旋的方向都得完全一致才算数。
最终,计算机把全图所有位置的“分数”列出来,分数最高(或最低,取决于算法)的那个点,就是它认为的“最佳匹配位置”。
二、 这位“福尔摩斯”有多死板?(三大致命弱点)
虽然模板匹配听起来很美好,但它有个致命的缺陷——它是一个“认死理”的直男。 它有三个绝对的“雷区”:
怕“长胖”或“变瘦”(尺度敏感性)
如果你的模板是50x50像素,但原图里的目标是100x100像素(缩放),哪怕只是稍微远了一点导致成像变小,计算机也会无情地判定:“不像!不匹配!”它不会像人类一样自动脑补比例。
怕“扭脖子”(旋转敏感性)
模板里是个正立的杯子,原图里的杯子如果只是歪了15度,计算机就会一脸懵逼:“这 curvature(曲率)不对啊,不是同一个杯子!”它眼里揉不得半点角度的沙子。
怕“换滤镜”(光照敏感性)
模板是在晴天室内拍的(亮度高),原图是在阴天拍的同一个地方(亮度低)。仅仅因为整体像素值都变了,模板匹配就可能直接罢工。
这就像你拿着爱豆十年前的护照照片去机场接机,结果爱豆换了发型、穿了宽松衣服,还晒黑了。模板匹配保准在你眼皮底下走过,你都认不出来,甚至还会报警说遇到了冒名顶替者!
三、 既然这么笨,为什么还要用它?(应用场景)
你可能会问:“这也不能干,那也不行,要它何用?”嘿,在特定的工业场景下,它可是性价比极高的“神器”!
1. 工业流水线上的“质检员”
在电子厂,需要确认电路板上的某个电容是不是被装反了,或者缺焊了。因为流水线上的物品位置、大小、角度都是严格固定的,光照也是恒定不变的。此时,模板匹配一秒钟能扫几百个,又快又准,简直是资本家的福音!只要环境绝对可控,它就是最快、最便宜的“流水线监工”。
2. 固定UI界面的“自动化测试猿”
程序员写了个脚本,想在电脑屏幕上自动点击某个软件的“确定”按钮。他只需要截个“确定”按钮的小图,然后用模板匹配在全屏找。因为UI界面通常不会自己缩放旋转,所以百发百中。代替苦逼打工人完成机械的鼠标点击,打工人的福音。
3. 简单的“找Logo”或“找图标”
比如在一堆杂乱的文件中,快速定位出所有的PDF图标或者微信的绿色气泡。只要图标本身没有变形变色,模板匹配依然是最轻量级的首选方案。
如果说边缘检测和形态学是图像的“骨科医生”,那么模板匹配就是个“认死理的门卫大爷”。它不懂变通,惧怕旋转、缩放和光照变化,但在环境受控、目标规整的特定场景下,它以其零训练成本、极易上手的优势,成为了无数轻量级自动化项目的首选方案。记住一句话:不要用全能AI的标准去要求一个只想好好“找茬”的算法。 只要把环境固定好,模板匹配绝对是你最忠诚、最勤快的像素打工人!
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_locsimilarity = 1 - min_val # 转成相似度else:top_left = max_locsimilarity = 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()

# 图像模板匹配 相关源码获取地址: https://pan.baidu.com/s/1ic_o7R6Sks2OeFyifCqL1A公众号私信发送【视觉源码】获取 提取码

点击【i怡心兮】- 右上角找到【…】
立刻设置为✨星标/置顶✨ ~ 谢谢 

夜雨聆风