本文作者:小嗷
微信公众号: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 给出了错误的匹配结果, 但是它们的归一化版本给出了正确的结果, 这或许是由于我们实际上仅仅考虑 “最匹配” 而没考虑其他可能的高匹配位置
领取专属 10元无门槛券
私享最新 技术干货