理解和评估模板匹配方法

19

OpenCV有matchTemplate()函数,它通过滑动模板输入到输出,并生成与匹配对应的数组输出。

我在哪里可以学习如何解释六种TemplateMatchModes

我已经阅读并实现了基于tutorial的代码,但除了理解一个寻找最小结果用于TM_SQDIFF匹配和其余情况下使用最大值之外,我不知道如何解释不同的方法以及选择其中一种的情况。

例如(摘自教程)

res = cv.matchTemplate(img_gray, template, cv.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(res >= threshold)

并且

R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }

我推断{{TM_CCOEFF_NORMED}}会返回0到1之间的值,并且0.8的阈值是任意的,但这只是猜测。
是否有更深入的方程式探讨、对标准数据集的性能测量或关于不同模式何时以及为什么使用其中一种的学术论文?

此外,这些问题是相关的,但并不完全涵盖上述内容: https://dev59.com/DV4b5IYBdhLWcg3w9FoI https://dev59.com/pKrka4cB1Zd3GeqPYBJN - VictorLegros
1
小细节:CCOEFF_NORMED 的结果在 [-1, 1] 范围内,而不是 [0, 1]。CCOEFF 是进行了平移处理,使得均值为 0,因此数值既有正数也有负数,然后进行乘法和除法运算...所以结果也可能是负数。 - alkasm
1个回答

54
所有的模板匹配模式可以大致归为密集(即像素级别)的相似度度量,或者等效但是相反的图像之间的距离度量。
一般来说,您会有两张图片,想以某种方式进行比较。模板匹配并不能直接帮助您匹配缩放、旋转或变形的物体。模板匹配严格关注于精确测量两个图像的相似性。然而,这里使用的实际指标在计算机视觉中随处可见,包括查找图像之间的变换......通常还有更复杂的步骤(如梯度下降来找到最佳的变换参数)。
有许多距离度量方法可供选择,它们通常根据应用程序具有优缺点。

绝对差的总和(SAD)

首先,最基本的距离度量就是两个值之间的绝对差,即d(x, y) = abs(x - y)。对于图像,从单个值扩展这个方法的一个简单方法是像素逐个地计算所有这些距离,从而得到绝对差的总和(SAD)指标;它也被称为曼哈顿或出租车距离,并定义了L1范数。令人烦恼的是,这并没有作为OpenCV的模板匹配模式之一实现,但在这个讨论中它仍然很重要,因为它可以与SSD进行比较。

在模板匹配场景中,您沿着多个位置滑动模板,只需找到最小差异发生的地方即可。这相当于在数组[1, 4, 9]中寻找最接近5的值的索引。您将每个数组中的值与5的绝对差计算出来,索引1具有最小的差异,因此那是最接近匹配的位置。当然,在模板匹配中,值不是5,而是一个数组,而且图像是一个更大的数组。

平方差的总和(SSD):TM_SQDIFF

SAD指标的一个有趣特性是,它不会惩罚大的差异,与许多小的差异一样。假设我们要使用以下向量计算d(a, b)d(a, c)

a = [1, 2, 3]
b = [4, 5, 6]
c = [1, 2, 12]

对每个元素取绝对差的和,我们可以看到

SAD(a, b) = 3 + 3 + 3 = 9 = 0 + 0 + 9 = SAD(a, c)

在某些应用程序中,这可能并不重要。但在其他应用程序中,您可能希望这两个距离实际上相差很大。将差异平方而不是取它们的绝对值会惩罚远离预期值的值-随着价值差异的增加,它使图像更加远离。它更符合某人可能会解释估计值偏离得非常远,即使在价值上实际上并不是那么远。平方差之和(SSD)等效于欧几里得距离的平方,欧几里得距离是L2范数的距离函数。使用SSD,我们可以看到这两个距离现在相差很大:
SSD(a, b) = 3^2 + 3^2 + 3^2 = 27 != 81 = 0^2 + 0^2 + 9^2 = SSD(a, c)

你可能会看到,L1范数有时被称为鲁棒范数。这是因为一个错误点不会使距离增加超过该错误本身。但是,对于SSD来说,异常值会使距离变得更大。因此,如果你的数据有几个非常远的值,那么请注意,SSD可能不是适合你的相似性度量。一个很好的例子可能是比较可能过曝的图像。在图像的某些部分,你可能只有白色天空,而其他部分则完全不是白色,这将导致图像之间的距离非常大。
SAD和SSD的最小距离都是0,当两个比较的图像完全相同时。它们都始终是非负的,因为绝对差异或平方差异始终是非负的。
交叉相关(CC):TM_CCORR
SAD和SSD通常都是离散的度量方法,因此它们是采样信号(如图像)的自然考虑因素。交叉相关也适用于连续的、因此是模拟的信号,这是其在信号处理中无处不在的一部分。对于广义的信号,在信号内检测模板的存在被称为匹配滤波器,并且你可以将其基本上视为模板匹配的连续模拟。

交叉相关只是将两个图像相乘。你可以想象,如果两个信号完全对齐,将它们相乘将简单地平方模板。如果它们没有完全对齐,那么乘积将更小。因此,乘积最大的位置是它们最好对齐的位置。然而,在你不确定使用它作为相似度测量的信号是否相关的情况下,交叉相关存在一个问题,通常在以下示例中显示。假设你有三个数组:

a = [2, 600, 12]
b = [v, v, v]
c = [2v, 2v, 2v]

总体而言,abac之间没有明显的相关性。一般来说,ab的相关性不应比与c更高。但是,由于这是一个产品,因此ccorr(a, c) = 2*ccorr(a, b)。因此,在尝试在较大图像中查找模板时,这并不理想。由于我们处理具有定义最大值(即图像)的离散数字信号,这意味着图像的明亮白色补丁基本上总是具有最大相关性。由于这个问题,TM_CCORR作为模板匹配方法并不特别有用。
均值偏移交叉相关(Pearson相关系数):TM_CCOEFF 解决与明亮补丁相关的问题的一种简单方法是在比较信号之前将平均值减去。这样,仅移动的信号与未移动的信号具有相同的相关性。这符合我们的直觉——变化一起的信号是相关的。
归一化:TM_SQDIFF_NORMEDTM_CCORR_NORMEDTM_CCOEFF_NORMED OpenCV中的所有方法都是以相同的方式进行归一化的。归一化的目的{{不是}}为了给出置信度/概率,而是为了给出一个度量标准,使您可以将其与不同大小或不同比例值的模板进行比较。例如,假设我们想要查找图像中是否存在对象,并且我们有两个不同大小的此对象的模板。我们可以通过像素数来归一化,这将适用于比较不同大小的模板。然而,假设我的模板在强度上实际上非常不同,例如一个像素值的方差比另一个高得多。通常,在这种情况下,您需要通过标准差(平均差的平方和的平方根)进行除法。OpenCV确实使用“TM_CCOEFF_NORMED”方法执行此操作,因为平均差的平方和{{就是}}方差,但其他方法没有进行平移,因此缩放只是图像值之和的度量。无论哪种方式,结果都是类似的,您希望按与所使用的图像补丁的强度相关的某些内容进行缩放。
其他度量标准

OpenCV没有提供的其他有用指标。Matlab提供了SAD,以及最大绝对差度量(MaxAD),也被称为均匀距离度量和给出L∞范数。基本上,您取最大绝对差而不是它们的总和。通常在优化设置中使用的其他指标,例如首先提出用于立体匹配的增强相关系数,然后扩展到一般的对准。该方法用于OpenCV,但不用于模板匹配;您将在computeECC()findTransformECC()中找到ECC指标。


使用哪种方法?

通常情况下,您会看到已归一化和未归一化的SSD(TM_SQDIFF_NORMEDTM_SQDIFF)以及零规范化互相关/ZNCC (TM_CCOEFF_NORMED)被使用。有时您可能会看到TM_CCORR_NORMED,但不太常见。根据我在网上找到的一些讲义笔记(这个主题有一些很好的例子和直观的解释!),Trucco和Verri的CV书指出,通常SSD比相关性更有效,但我没有T&V的书来看看他们为什么建议这样做;大概是因为比较是基于真实世界的照片。但尽管如此,SAD和SSD绝对是有用的,特别是对于数字图像。

我不知道任何一个在大多数情况下哪种更好的确定性例子或类似的东西---我认为它真的取决于您的图像和模板。通常我会说:如果您正在寻找精确匹配或非常接近的匹配,请使用SSD。它很快,而且它肯定映射到您要最小化的内容(模板和图像块之间的差异)。在这种情况下,没有必要归一化,这只是额外的开销。如果您有类似的要求,但需要比较多个模板,则将SSD归一化。如果您正在寻找匹配,但您正在处理可能具有曝光或对比度差异的真实世界照片,则ZNCC的平移和方差均衡很可能是最好的。

关于选择正确的阈值,从 ZNCC 或 SSD 得到的值根本不是置信度或概率数字。如果你想选择正确的阈值,可以通过多种典型方式来测量参数。你可以为不同的阈值计算 ROC 曲线或 PR 曲线。你可以使用回归来找到最佳参数。你需要标记一些数据,但至少你会有针对某个测试集的表现测量结果,这样你的选择就不是随意的。通常情况下,对于一个数据密集型领域,你需要确保你的数据尽可能接近真实世界的例子,并且你的测试数据涵盖了你的边缘情况以及典型图像。

我想知道你是否可以为我澄清一些事情。当你谈论规范化时,你提到了同一对象的两个不同模板。但是,在我的项目中,我正在搜索一个单一的图像以获取多个对象,其中只有一个对象实际上应该存在。TM_CCOEFF_NORMED适用于这种情况吗?也就是说,无论它们的大小或强度如何,存在的对象的模板是否可靠地产生比缺失对象的更高的输出? - Jordak
1
@Jordak 实际上,在那里也适用相同的方法;您肯定会想要为该任务使用归一化。我建议从TM_CCOEFF_NORMEDTM_CCORR_NORMED开始——使用相关系数进行均值偏移可能需要,也可能不需要,这取决于图像输入(例如,如果您希望模板和图像中的对象的强度相等,则交叉相关应该就足够了; 如果您需要对不同光照具备鲁棒性,则使用相关系数)。 - alkasm
您提到:“然而,假设我的模板在强度上实际上是非常不同的,比如一个像素值的方差比另一个高得多。通常,在这种情况下,您需要做的是除以标准差(平均差的平方根)。” 然而,实际上交叉相关公式并没有从平方和中减去平均值。您能解释一下为什么吗? - Freeman
1
@Freeman 当你有两个信号/图像,它们本质上是相同的,只是彼此之间移位时,交叉相关更常用。在这种情况下,规范化或均值偏移并不特别必要。然而,在试图开发两个信号之间的线性关系时,皮尔逊相关系数(即TM_CCOEFF_NORMED计算的内容)给出了两个信号之间依赖关系的更有意义的分数。 - alkasm
此外,相关系数的计算成本要高得多——交叉相关可以使用积分图像来计算,但是在相关系数计算中的均值漂移无法使用积分图像实现。 - alkasm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接