1、模板匹配概述
大家好,我是老张。做嵌入式视觉这些年,模板匹配是我用得最多的算法之一。说实话,它不是什么高大上的深度学习,但胜在简单、稳定、资源消耗低。今天咱们就来聊聊这个经典算法。
什么是模板匹配
模板匹配,说白了就是在一张大图里找一张小图。你有一张模板图(比如一个芯片的引脚),然后在一张更大的图像里搜索,看看有没有和模板相似的地方。
我习惯这么理解:就像你在人群里找一个人,你脑子里有他的样子,然后扫视全场,找到最像的那个位置。模板匹配干的就是这个事。
数学上,它是在图像上滑动一个窗口,计算窗口内容和模板的相似度。相似度最高的位置,就是匹配结果。
核心思想:模板匹配 = 滑动窗口 + 相似度计算
应用场景
我在项目里用过模板匹配的场景还真不少。大致分三类:
定位
这是最常见的用法。比如PCB板上的元件定位,我需要知道芯片焊盘在哪个位置,才能引导机械臂去抓取。模板匹配在这里就是找坐标。
我记得有个项目,客户要求在30ms内定位手机主板上的12个测试点。用模板匹配,配合金字塔加速,稳稳地跑在25ms以内。
检测
检测和定位不太一样。定位是找位置,检测是判断有没有、好不好。
- 有无检测:生产线上有没有漏贴元件
- 缺陷检测:印刷字符有没有缺笔少画
- 完整性检测:连接器针脚有没有弯折
嗯,这里要注意:检测场景对光照变化比较敏感。我曾经在一个产线项目里吃过亏,白天和晚上的检测率差了10%。后来加了预处理才搞定。
识别
识别比定位和检测更进一步。它要回答"这是什么"。
- 识别不同型号的芯片
- 识别电路板上的丝印字符
- 识别元器件的极性方向
不过说实话,纯模板匹配做识别能力有限。遇到旋转、缩放、形变大的情况,我一般会建议用特征匹配或者深度学习。
算法分类
模板匹配算法分两大类。我按自己的理解给你捋一捋。
基于灰度的方法
这类方法直接用像素灰度值做计算。简单粗暴,适合嵌入式。
| 方法 | 原理 | 特点 |
|---|---|---|
| 平方差匹配 | 计算像素差值的平方和 | 值越小越匹配,对光照敏感 |
| 相关系数匹配 | 计算归一化相关系数 | 值越大越匹配,抗光照干扰 |
| 归一化互相关 | 归一化后的互相关计算 | 最稳定,但计算量大 |
我个人习惯在嵌入式上用归一化互相关。虽然慢一点,但省心。你想想看,产线上光照变来变去,用平方差匹配,阈值根本没法设。
实战建议:在ARM Cortex-A系列上,归一化互相关用NEON指令优化后,速度能提升3-5倍。我之前的项目就是这么干的。
基于特征的方法
这类方法先提取特征,再匹配特征。常见的特征有边缘、角点、轮廓等。
- 边缘匹配:用Canny提取边缘,然后匹配边缘图
- 形状匹配:用轮廓的矩或者形状上下文
- 特征点匹配:用SIFT、SURF、ORB等
基于特征的方法好处很明显:对光照不敏感,能处理部分遮挡。但代价是计算量大,在低端MCU上跑不动。
避坑指南:我曾经在一个项目里用ORB特征匹配做元件定位,结果在STM32H7上跑到了200ms一帧。后来老老实实换回了灰度模板匹配,优化后只要15ms。选算法一定要看硬件资源。
怎么选?我的经验
说了这么多,到底怎么选?我一般按这个思路来:
- 先看硬件:MCU还是MPU?有没有FPU?内存多大?
- 再看场景:光照稳不稳定?有没有旋转缩放?
- 最后看精度:亚像素精度要求高不高?
说白了,嵌入式上90%的场景用归一化互相关就能搞定。剩下的10%,要么加预处理,要么上特征匹配。别一上来就整复杂的,先跑通再说。
我的原则:能用灰度匹配解决的,绝不用特征匹配。能用特征匹配解决的,绝不用深度学习。嵌入式资源有限,简单就是美。
好了,这一章就聊到这儿。下一章咱们深入讲讲归一化互相关的数学原理和嵌入式优化技巧。到时候我会拿一个实际项目案例来拆解,保证干货满满。