1、模板匹配概述

大家好,我是老张。做嵌入式视觉这些年,模板匹配是我用得最多的算法之一。说实话,它不是什么高大上的深度学习,但胜在简单、稳定、资源消耗低。今天咱们就来聊聊这个经典算法。

什么是模板匹配

模板匹配,说白了就是在一张大图里找一张小图。你有一张模板图(比如一个芯片的引脚),然后在一张更大的图像里搜索,看看有没有和模板相似的地方。

我习惯这么理解:就像你在人群里找一个人,你脑子里有他的样子,然后扫视全场,找到最像的那个位置。模板匹配干的就是这个事。

数学上,它是在图像上滑动一个窗口,计算窗口内容和模板的相似度。相似度最高的位置,就是匹配结果。

核心思想:模板匹配 = 滑动窗口 + 相似度计算

应用场景

我在项目里用过模板匹配的场景还真不少。大致分三类:

定位

这是最常见的用法。比如PCB板上的元件定位,我需要知道芯片焊盘在哪个位置,才能引导机械臂去抓取。模板匹配在这里就是找坐标。

我记得有个项目,客户要求在30ms内定位手机主板上的12个测试点。用模板匹配,配合金字塔加速,稳稳地跑在25ms以内。

检测

检测和定位不太一样。定位是找位置,检测是判断有没有、好不好。

  • 有无检测:生产线上有没有漏贴元件
  • 缺陷检测:印刷字符有没有缺笔少画
  • 完整性检测:连接器针脚有没有弯折

嗯,这里要注意:检测场景对光照变化比较敏感。我曾经在一个产线项目里吃过亏,白天和晚上的检测率差了10%。后来加了预处理才搞定。

识别

识别比定位和检测更进一步。它要回答"这是什么"。

  • 识别不同型号的芯片
  • 识别电路板上的丝印字符
  • 识别元器件的极性方向

不过说实话,纯模板匹配做识别能力有限。遇到旋转、缩放、形变大的情况,我一般会建议用特征匹配或者深度学习。

算法分类

模板匹配算法分两大类。我按自己的理解给你捋一捋。

基于灰度的方法

这类方法直接用像素灰度值做计算。简单粗暴,适合嵌入式。

方法 原理 特点
平方差匹配 计算像素差值的平方和 值越小越匹配,对光照敏感
相关系数匹配 计算归一化相关系数 值越大越匹配,抗光照干扰
归一化互相关 归一化后的互相关计算 最稳定,但计算量大

我个人习惯在嵌入式上用归一化互相关。虽然慢一点,但省心。你想想看,产线上光照变来变去,用平方差匹配,阈值根本没法设。

实战建议:在ARM Cortex-A系列上,归一化互相关用NEON指令优化后,速度能提升3-5倍。我之前的项目就是这么干的。

基于特征的方法

这类方法先提取特征,再匹配特征。常见的特征有边缘、角点、轮廓等。

  • 边缘匹配:用Canny提取边缘,然后匹配边缘图
  • 形状匹配:用轮廓的矩或者形状上下文
  • 特征点匹配:用SIFT、SURF、ORB等

基于特征的方法好处很明显:对光照不敏感,能处理部分遮挡。但代价是计算量大,在低端MCU上跑不动。

避坑指南:我曾经在一个项目里用ORB特征匹配做元件定位,结果在STM32H7上跑到了200ms一帧。后来老老实实换回了灰度模板匹配,优化后只要15ms。选算法一定要看硬件资源。

怎么选?我的经验

说了这么多,到底怎么选?我一般按这个思路来:

  1. 先看硬件:MCU还是MPU?有没有FPU?内存多大?
  2. 再看场景:光照稳不稳定?有没有旋转缩放?
  3. 最后看精度:亚像素精度要求高不高?

说白了,嵌入式上90%的场景用归一化互相关就能搞定。剩下的10%,要么加预处理,要么上特征匹配。别一上来就整复杂的,先跑通再说。

我的原则:能用灰度匹配解决的,绝不用特征匹配。能用特征匹配解决的,绝不用深度学习。嵌入式资源有限,简单就是美。

好了,这一章就聊到这儿。下一章咱们深入讲讲归一化互相关的数学原理和嵌入式优化技巧。到时候我会拿一个实际项目案例来拆解,保证干货满满。