简介
模板匹配是一种高级计算机视觉方法,可检测与预定模板匹配的图像部分。先进的模板匹配算法检测模板的出现,无论其方向或局部亮度如何。
在医学图像分析中,不变特征或创新应用通常用作对象识别领域,例如车辆跟踪、机器人和制造。
模板匹配方法用途广泛且易于应用,使其成为最常用的对象定位方法之一。它们的实用性主要受计算机容量的限制,因为识别大型复杂模板可能很耗时。
· 这是一种在较大图像中搜索和定位模板的方法。
· 目标是发现与我们基于阈值提供的模板匹配的图像的相同部分。
· 阈值决定了我们想要识别原始图像中的模板的程度。
· 例如,如果我们正在使用人脸识别,并且想要检测人的眼睛,我们可以使用眼睛的随机图像作为模板并搜索源(人脸)。
· 在这种情况下,由于“眼睛”因人而异,即使我们将阈值设置为 50%(0.5),眼睛也会被识别出来。
工作功能
· 只需将模板图片滑动到输入图像上(如在 2D 卷积中)
· 比较模板图片和它下面的输入图像。
· 将获得的结果与阈值进行比较。
· 如果结果超过阈值,则将该部分标记为检测到。
· 函数cv2.matchTemplate(image, template,cv2.TM_CCOEFF_NORMED)中的第一个参数是主图像,第二个参数是要匹配的模板,第三个参数是匹配技术。
让我们首先定义模板匹配。它是一种在源图像中定位参考图像(或模板图像)的方法。在其最基本的形式中,该算法比较每个源图像区域的模板,一次一个像素。这被称为互相关。此过程的结果是另一个图像,其像素值对应于模板图像在该像素位置插入时与源图像的相似程度。
让我们看一下金属瓶盖的图像,看看它是如何工作的。假设我们对红色金属瓶盖感兴趣。
让我们编码
让我们看看它在 Python 中的实现!但首先,我们必须导入以下库:
import cv2
import numpy as np
让我们加载一个源图像并将你的 RGB 源图像转换为灰度(它的二值化形式也可以工作)。彩色照片可用于模板匹配,但灰度或二值化图像更易于使用。
python 代码:
# import the necessary packages
import cv2
img = cv2.imread("32080download.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("Output", img)
cv2.waitKey(0)
输出:
要在上图中进行模板匹配,首先,我们必须加载模板图像
template = cv2.imread(r"template_image_path")
w, h = template.shape[::-1]
在将模板的宽度和高度存储在 w 和 h 中之后,我们初始化一个发现的变量来跟踪具有最佳匹配的图像的区域和比例。使用模板匹配功能检测输入源图像中的模板,
res = cv2.matchTemplate(gray, template, cv2.TM_CCOEFF_NORMED)
之后,设置所需输出的阈值
threshold = 0.90
loc = np.where(res >= threshold)
在模板匹配对象中绘制矩形
for pt in zip(*loc[::-1]):
cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 0, 255),1)
显示带有标记模板区域的源图像
cv2.imshow('Detected the template matching objects', img)
cv2.imshow('Template', template)
cv2.waitKey()
cv2.destroyAllWindows
我们可以利用多重缩放来避免模板和原始图像大小不同所带来的问题。
多尺度——新的模板匹配方法
如果你的模板尺寸与你要匹配的图像中区域的尺寸不匹配,这并不妨碍你使用模板匹配。
多重缩放过程如下:
以各种比例循环输入图像。使用 cv2.matchTemplate,应用模板匹配并跟踪具有最高相关系数的匹配(以及具有最大相关系数的区域的 x 和 y 坐标)。循环遍历所有尺度后,选择相关系数最高的区域作为匹配区域。
import cv2
import imutils
import numpy as np
img_rgb = cv2.imread('mainimage.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('template', 0)
w, h = template.shape[::-1]
resize = imutils.resize(img_gray, width=int(img_gray.shape[0]), height=int(img_gray.shape[1]*scale)
if resized.shape[0] < h or resized.shape[1] < w:
break
found=(maxVal, maxLoc, r)
(__, maxLoc, r)=found
(startX, startY)=(int(maxLoc[0]*r), int maxLoc[1]*r)
(finalX, finalY)=(int((maxLoc[0]+tw)*r), int(maxLoc[1]+tH)*r)
cv2.rectangle(image, (startX, startY),(finalX, finalY), (255, 0, 255), 2)
cv2.imshow("Image", image)
cv2.waitKey(0)
以下是对上述代码的分步说明:
我们在 w 和 r 中记录模板的宽度和高度后,初始化一个变量来跟踪最匹配的图像的区域和比例。然后,使用 np.linspace 函数,我们开始遍历图像的众多比例。这个函数接受三个参数:起始值和结束值以及它们之间相等的块切片的数量。在此示例中,我们将从原始图像大小的 100% 开始,然后在 20 个相同大小的百分比块中缩小到原始大小的 20%。
我们接下来将图像调整为当前比例并计算旧宽度与新宽度的比率——正如你稍后将看到的,这个比率很关键。我们验证提供的图像是否大于我们的模板匹配。如果模板更大,我们的 cv2.matchTemplate 调用将失败。因此,在这种情况下,我们只是退出循环。我们现在可以将模板匹配应用于我们的缩放图像:
我们的相关结果被传递给 cv2.minMaxLoc 函数,该函数返回一个 4 元组,其中包含最小相关值、最大相关值、最小值的 (x, y) 坐标和最大值的坐标 (x, y)。
因为我们只想要最大值和 (x, y) 坐标,所以我们保存最大值并拒绝最小值。之后,我们在每次缩放迭代中检查匹配的图像区域。然后,我们更新我们发现的变量以跟踪迄今为止发现的最大相关值、最大值的 (x, y) 坐标以及原始图像宽度与当前放大图像宽度的比率。
在遍历所有图片比例后,我们提取我们的found变量并计算我们的边界框的开始和结束 (x, y) 坐标。
结论
本文演示了我们如何使用图像处理来辅助对象检测和识别。模板匹配可用作检测机器学习和深度学习模型的对象的管道。
要点:
· 参考图案的方向必须在模板中保留。
· 因此,它不适用于模板的旋转或缩放版本,因为围绕模板的对象的形状/大小/剪切等的变化会导致错误匹配。
· 由于该过程耗时,该方法在计算中大型图像的模式相关图像时效率低下。
原文标题 : 对象检测:模板匹配