52.模板匹配-OpenCV从零开始到图像识别

本文作者:小嗷

微信公众号:aoxiaoji

链接:https://f600lt.github.io/archives/

在本篇中,您将学习:

使用OpenCV函数matchTemplate()搜索图像补丁和输入图像之间的匹配

使用OpenCV函数minMaxLoc()查找给定数组中的最大值和最小值(以及它们的位置)。

本文你会找到以下问题的答案:

matchTemplate()

minMaxLoc()

2.1 模板匹配是什么?

模板匹配是一种查找与模板图像(patch)匹配(相似)的图像区域的技术。

虽然补丁必须是一个矩形,但可能不是所有的矩形都是相关的。在这种情况下,可以使用掩码隔离用于查找匹配的补丁的部分。

实际上是如何操作呢?

我们需要两个主要部分:

Source image (I):希望找到与模板图像匹配的图像

Template image (T):将与模板图像进行比较的patch图像

我们的目标是检测最高匹配区域:

为了识别匹配区域,我们必须通过滑动模板图像与源图像进行比较:

通过滑动,小嗷的意思是每次移动一个像素(从左到右,从上到下)。在每个位置上,都会计算一个度量值,以表示该位置匹配的“好”或“坏”(或该补丁与源图像的特定区域的相似性)。

对于T / I的每个位置,将每个位置的匹配结果存储在R矩阵中,该矩阵的每一个点的亮度表示与模板图像T的匹配程度。

上面的图像是用一个指标TMCCORRNORMED来滑动patch的结果。最亮的位置代表最高的匹配。如您所见,红色圆圈标记的位置可能是值最高的位置,因此位置(由该点构成的矩形为角,宽度和高度等于patch图像)被认为是匹配的。

在实践中,我们使用minMaxLoc()函数在R矩阵中查找最大值(或者更低,取决于匹配方法的类型)

如果匹配需要掩膜,则需要三个组件:

Source image (I): 我们希望在其中找到与模板映像匹配的映像

Template image (T):将与模板图像进行比较的patch图像

Mask image (M): 掩膜图片,(掩膜模板的灰度图像)

目前只有两个匹配方法接受掩码:CVTMSQDIFF和CV_TMCCORRNORMED(有关opencv中可用的所有匹配方法的解释,请参阅下面)。

掩膜必须具有与模板相同的维度

掩膜应该具有CV8U或CV32F深度和与模板映像相同的通道数量。

在CV_8U情况下,掩膜值被视为二进制值,即零和非零。

在CV_32F中,值应该落在[0..1]范围和模板像素将乘以相应的掩膜像素值。

由于示例中的输入图像具有CV_8UC3类型,因此掩膜也被读取为彩色图像。(看不懂,不懂问小嗷吧)

OpenCV中有哪些匹配方法?

OpenCV在matchTemplate()函数中实现模板匹配。可用的方法有6种:

3.1 minMaxLoc()

在数组中查找全局最小值和最大值。

函数cv::minMaxIdx查找最小和最大元素值及其位置。在整个数组中搜索极值,如果掩码不是空数组,则在指定的数组区域中搜索。该函数不适用于多通道数组。

如果您需要在所有通道中找到最小或最大的元素,首先使用Mat::reshape 将数组重新解释为单通道。或者您可以使用extractImageCOI提取特定的通道,或者混合通道,或者分裂。对于稀疏矩阵,只在非零元素中找到最小值。

注意:当minIdx不是NULL时,它必须至少有2个元素(以及maxIdx),即使src是单行或单列矩阵。在OpenCV(下面是MATLAB)中,每个数组至少有两个维度,即单列矩阵是Mx1矩阵(因此minIdx/maxIdx将是(i1,0)/(i2,0)),单行矩阵是1xN矩阵(因此minIdx/maxIdx将是(0,j1)/(0,j2))。

當我們得到比較圖後,根據由比較方式,選擇比較圖最小或最大值的地方,就是目標影像的位置。

src:輸入圖。

minVal:極小值,可輸入NULL表示不需要。

maxVal :極大值,可輸入NULL表示不需要。

minLoc:極小值的位置,可輸入NULL表示不需要。

maxLoc:極大值的位置,可輸入NULL表示不需要。

mask:可有可無的遮罩。

3.2 matchTemplate()

将模板与重叠的图像区域进行比较。

函数通过图像进行滑动,比较了重叠补丁的大小 w × h 对templ使用指定的方法并存储结果的比较结果(方差之类的公式上面已经讲了),下面是可用比较方法的公式(I表示图像,T模板,R结果)。求和完成模板and/or图像补丁:x′= 0 w−1,y′= 0…h−1

在函数完成比较之后,可以使用minMaxLoc函数找到最佳匹配的全局极小值(使用TM_SQDIFF时)或极大值(使用TM_CCORR或TM_CCOEFF时)。在彩色图像中,分子上的模板和分母上的每个和都在所有的通道上进行求和,每个通道使用单独的平均值。也就是说,该函数可以获取一个颜色模板和一个颜色图像。结果仍然是单通道图像,更容易分析。

模板匹配算法

可用的方法有6个:

通常,随着从简单的测量(平方差)到更复杂的测量(相关系数),我们可获得越来越准确的匹配(同时也意味着越来越大的计算代价). 最好的办法是对所有这些设置多做一些测试实验,以便为自己的应用选择同时兼顾速度和精度的最佳方案.

image:搜索正在运行的图像。它必须是8位或32位浮点数。(原图)

templ:搜索模板。它必须不大于源映像,并且具有相同的数据类型。

result:比较结果的映射图像。单通道、32-比特浮点数. 如果图像是 W×H而 templ 是 w×h ,则 result 一定是 (W-w+1)×(H-h+1).

method:参数指定比较方法,请参阅TemplateMatchModes

mask:搜索模板的Mask。它必须具有与templ相同的数据类型和大小。它不是默认设置的。目前,只支持TMSQDIFF和TMCCORR_NORMED方法。

忘了统计学原理请看回50篇,谢谢。还有小嗷的文章是累加的,如果出现大面积看不懂,请从头开始谢谢。不懂就进群问小嗷

模板匹配是一种最原始、最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题。它是图像处理中最基本、最常用的匹配方法。模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。

本篇文章的代码如下所示。

解释一下:

声明一些全局变量,如图像、模板和结果矩阵,以及匹配方法和窗口名称:

加载源图像、模板,如果匹配方法支持,还可以选择使用掩码:

创建Trackbar输入要使用的匹配方法。当检测到更改时,将调用回调函数。

让我们检查回调函数。首先,对源图像进行复制:

执行模板匹配操作。参数自然是输入图像I、模板T、结果R和match_method(由Trackbar提供),以及可选的掩码图像M。

很自然地,参数是输入图像 I, 模板图像 T, 结果图像 R 还有匹配方法 (通过滑动条给出)

我们对结果进行归一化:

通过使用函数 minMaxLoc ,我们确定结果矩阵 R 的最大值和最小值的位置.

函数中的参数有:

对于前二种方法 ( CV_SQDIFF 和 CV_SQDIFF_NORMED ) 最低的数值标识最好的匹配. 对于其他的, 越大的数值代表越好的匹配. 所以, 我们在 matchLoc 中存放相符的变量值:

结果

用输入图像测试我们的程序,例如:

还有一幅模版图像:

产生了一下结果图像矩阵 (第一行是标准的方法 SQDIFF, CCORR 和 CCOEFF, 第二行是相同的方法在进行标准化后的图像). 在第1列, 最黑的部分代表最好的匹配, 对于其它2列, 越白的区域代表越好的匹配.

Result_0

Result_1

Result_2

Result_3

Result_4

Result_5

正确的匹配在上面有显示 (右侧被矩形标注的人脸). 需要注意的是方法 CCORR 和 CCOEFF 给出了错误的匹配结果, 但是它们的归一化版本给出了正确的结果, 这或许是由于我们实际上仅仅考虑 “最匹配” 而没考虑其他可能的高匹配位置

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180815G0FTYQ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券