让我们详细解释模板匹配如何在一张较大图像(源图像)中查找一张较小图像(模板)。这项核心技术依赖于一种系统搜索过程,通常称为“滑动窗口”方法。
想象一下,你有一张小的模板图像,也许是你想查找的某个特定图标的图片。你还有一张较大的源图像,你认为这个图标可能出现在其中。
- 滑动窗口: 模板匹配开始时,将模板放置到源图像的左上角。然后,它将模板直接与当前重叠的源图像图像块进行比较。
- 逐像素比较: 在此位置,算法计算一个分数,用以量化 (quantization)模板与底层图像块的匹配程度。有几种方法可以计算此分数,每种方法都有各自的优点。常用方法包括:
- 平方差之和 (SSD): 此方法计算模板中每个像素的强度值与源图像块中对应像素之间的差值。它将这些差值平方(使它们都变为正数),然后将它们全部相加。完美的匹配将导致 SSD 分数为 0,因为任何对应像素之间都没有差异。SSD 分数越小,该位置的匹配越好。
- 归一化 (normalization)互相关 (NCC): 这是一种常用方式,尤其当模板与源图像之间的整体亮度可能存在差异时。它计算模板与图像块之间的统计相关性,结果分数通常在 -1.0 和 1.0 之间(有时归一化到 0.0 到 1.0)。分数为 1.0 表示完美正相关(极佳匹配),0 表示没有相关性,-1.0 表示完美负相关(就像匹配照片底片)。对于 NCC,分数越高表示匹配越好。
- 系统滑动: 计算完初始左上角位置的分数后,算法将模板向右“滑动”一个像素,并重复比较,为这个新位置计算一个新分数。它会继续这个过程,使模板滑动到源图像的整个宽度。
- 向下移动: 一旦到达右边缘,它会将模板移回左边缘,但会向下移动一个像素。然后它会在此新行上滑动,为每个位置计算分数。
- 覆盖所有位置: 这种滑动(从左到右,从上到下)一直持续,直到模板与源图像中所有可能完全适合的图像块进行比较。
模板 (T) 被系统地放置在源图像 (I) 的不同位置 (u, v) 上。在每个位置,都会计算一个相似度分数,然后模板滑动到下一个位置。
- 结果图: 随着模板的滑动,在每个位置 (u,v) 计算的分数有效地创建了一个新的二维图,通常称为相关图或相似度图。此图的尺寸与源图像和模板图像之间的大小差异有关。此结果图中的每个像素表示模板在源图像中可能的左上角起始位置,其值包含该位置的匹配分数。
- 查找最佳匹配: 最后一步是简单地查找相似度图中具有“最佳”分数的位置。如果使用 SSD,则查找最小值(最小差异)。如果使用 NCC,则查找最大值(最高相关性)。相似度图中此最佳分数的坐标会告诉你原始源图像中模板匹配最接近的左上角 (x,y)。
这种滑动窗口比较是基本模板匹配背后的根本机制。像 OpenCV 这样的库提供了优化函数(如 cv2.matchTemplate),它们能非常高效地执行这些计算,让你能够轻松地在代码中应用此技术,这将在即将到来的练习部分中看到。