前面已经做过 ORB 特征匹配,这次换一种完全不同的思路:
Template Matching,模板匹配。
这次我用华为云码道辅助开发了一个 OpenCV 模板匹配工具,通过把一张小模板在大图中不断滑动,寻找局部结构最相似的位置。
1. 这次工具做什么?
主要功能包括:
- 上传 Source Image
- 上传 Template Image
- 使用 OpenCV Template Matching
- 调节 Match Threshold
- 自动寻找 Best Match
- 显示 Best Match Score
- 显示 Best Match Position
- 显示 Template Size
- 统计 Match Count
- 支持下载匹配结果
整体流程:
Source Image
→ Template Image
→ 滑动比较
→ Similarity Map
→ Best Match
→ Threshold Filtering
2. 什么是模板匹配?
模板匹配可以简单理解成:
拿着一张小图片,在大图上从左到右、从上到下不断移动。
每移动一个位置,就比较:
当前区域和模板到底有多像。
最后就可以找到:
相似度最高的位置。
这和 ORB Feature Matching 不一样。
ORB 比较的是局部特征点描述子,而 Template Matching 更接近:
直接比较局部图像结构。
3. 核心代码怎么实现?
这次使用:
result = cv2.matchTemplate( source_gray, template_gray, cv2.TM_CCOEFF_NORMED)其中:
TM_CCOEFF_NORMED
会输出一个归一化的相似度响应图。
再通过:
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)就可以得到:
- 最佳匹配分数
- 最佳匹配位置
这次:
Best Match Score = 0.3570
4. Best Match Position 是什么?
本次最终得到:
Best Match Position = (250, 365)
这个位置表示:
模板在 Source Image 中滑动时,
相似度最高的区域左上角坐标是:
X = 250 Y = 365再结合模板尺寸:
1119 × 211
就可以计算出完整矩形框的位置。
页面中的红色矩形就是根据这个结果绘制出来的。
5. Threshold 有什么作用?
这次设置:
Match Threshold = 0.80
Threshold 的作用是:
只把相似度足够高的位置认为是:
真正匹配。
例如:
locations = np.where( result >= 0.8)只有 Match Score ≥ 0.80 的位置,才会进入匹配结果。
所以 Threshold 越高:
结果越严格。
Threshold 越低:
会保留更多候选区域。
6. 真实测试结果
这次测试结果:
- Match Threshold:0.80
- Best Match Score:0.3570
- Best Match Position:(250, 365)
- Template Size:1119 × 211
- Match Count:0
也就是说:
虽然算法成功找到了整张图中“最相似”的区域,
但是这个最高分只有:
0.3570
并没有达到:
0.80
所以最终:
Match Count = 0
7. 为什么 Match Count 是 0 还有红框?
这个地方很容易误解。
Best Match 和 Threshold Match 是两个不同概念。
Best Match 表示:
所有候选位置里分数最高的那个。
即使它只有:
0.357
它依然是“最高分”。
而 Match Count 统计的是:
真正超过 Threshold 的位置数量。
本次:
Best Score = 0.3570 Threshold = 0.80因为:
0.3570 < 0.80
所以:
Match Count = 0
页面仍然显示红框,是为了告诉我们:
“虽然没有达到设定阈值,但最相似的位置在这里。”
这个设计反而很方便分析。
8. 为什么这次匹配分数不高?
本次 Template Size:
1119 × 211
是一个比较宽的横向模板。
其中包含的不只是狗狗,还包含了:
湖面
背景
草地
局部主体
Template Matching 对以下变化比较敏感:
- 尺度变化
- 旋转
- 裁剪差异
- 局部内容变化
所以最终:
Best Match Score = 0.3570
说明 Source Image 中并不存在一个和当前模板高度一致的区域。
这正好体现了模板匹配的局限。
9. 和 ORB Feature Matching 有什么区别?
前面做过 ORB Matching。
ORB 的特点是:
先检测关键点,再比较描述子。
所以它对一定程度的:
旋转
局部变化
尺度差异
会更有适应能力。
而 Template Matching 更像:
整块模板直接进行局部相似度比较。
因此它更适合:
模板大小接近
方向基本一致
目标外观变化较小
的场景。
比如:
按钮检测
图标定位
固定零件识别
界面元素查找
10. 总结
这次用华为云码道辅助开发了一个:
OpenCV 模板匹配工具。
核心流程:
Source Image
→ Template
→matchTemplate()
→ Similarity Map
→ Best Match
→ Threshold Filtering
本次真实结果:
- Match Threshold:0.80
- Best Match Score:0.3570
- Best Match Position:(250, 365)
- Template Size:1119 × 211
- Match Count:0
这次结果也说明一个很重要的问题:
“找到最相似的位置”不等于“匹配成功”。
真正是否接受这个结果,还需要看:
Best Match Score 是否超过设定的 Threshold。
所以模板匹配本质上不仅是在找位置,也是在做一次:
相似度判断。
下一篇可以继续换一个不重复的方向: