天天看点

opencv 模板匹配_使用模板匹配在Python上进行对象检测!(附代码)检测一个物体-最准确的物体检测多个对象-在给定阈值下

了解如何在没有机器学习或任何框架的情况下在Python上进行对象检测

opencv 模板匹配_使用模板匹配在Python上进行对象检测!(附代码)检测一个物体-最准确的物体检测多个对象-在给定阈值下

每当我们听说“ 对象检测 ”时,我们就会想到机器学习以及不同的框架。但是我们实际上可以在不使用机器学习或任何其他框架的情况下进行对象检测。在本文中,我将向您展示如何仅使用Python进行操作。

将从定义模板图像(对象)开始,然后系统将在源图像中找到与我们选择的模板匹配的所有其他对象。因此,让我解释一下向您展示示例的含义。在下面有两张图片,左侧是飞机的原图像,右侧是飞机作为对象的模板照片。

opencv 模板匹配_使用模板匹配在Python上进行对象检测!(附代码)检测一个物体-最准确的物体检测多个对象-在给定阈值下
opencv 模板匹配_使用模板匹配在Python上进行对象检测!(附代码)检测一个物体-最准确的物体检测多个对象-在给定阈值下

要写的是python代码,以显示此模板图像实际适合我的源图像的所有区域。

首先,让我们开始检测一个对象,其次,我们可以调整代码以检测多个对象。

检测一个物体-最准确的物体

为此,我们需要一个源图像和一个模板图像。模板图像在源图像上滑动(如2D卷积),程序将尝试找到最准确的匹配项。

让我们开始编码。

import cv2import numpy as npfrom matplotlib import pyplot as pltimg_rgb = cv2.imread('SourceIMG.jpeg')img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)template = cv2.imread('TemplateIMG.jpeg', 0)
           

在代码的以上部分中,我们使用OpenCV读取SourceIMG.jpeg和TemplateIMG.jpeg。

height, width = template.shape[::]
           

当模板图像滑到源图像上方时,它正在寻找整个区域。(将左上角作为参考框)。模板图像与原图像匹配后,我们要记下左上角的位置,然后在其实际匹配的区域周围绘制一个框。为此,我们需要找到此模板图像的高度和宽度。这样我们就可以绘制矩形了。

res = cv2.matchTemplate(img_gray, template, cv2.TM_SQDIFF)
           

模板匹配是OpenCV的一部分,它获取我们的灰度源图像和模板图像以及我们需要使用的统计指标。在这种情况下,我使用的是最小平方差(TM_SQDIFF),因为我们正在寻找模板图像和源图像之间的最小差。

plt.imshow(res, cmap='gray')
           

如果您绘制了到目前为止所做的事情,我们将看到一个概率图。从下图可以看到,这些小点是模板实际匹配的位置。

opencv 模板匹配_使用模板匹配在Python上进行对象检测!(附代码)检测一个物体-最准确的物体检测多个对象-在给定阈值下

概率图

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
           

使用上面的代码,我们可以找到概率图中微小点的位置。使用minMaxLoc(res)我们可以提取最小值,最大值,最小位置和最大位置。

top_left = min_loc bottom_right = (top_left[0] + width, top_left[1] + height)cv2.rectangle(img_rgb, top_left, bottom_right, (255, 0, 0), 2)
           

为了在模板图像匹配的源图像上绘制一个蓝色矩形,我们需要获得最小位置min_loc(实际开始匹配的位置)作为左上角。以同样的方式,我们可以通过top_left[0] + width和使我们的底部正确top_left[1] + height。通过这些尺寸,我们可以使用绘制蓝色矩形cv2.rectangle。

这就是我们需要设置的所有内容,让我们继续进行可视化处理。

cv2.imshow("Matched image", img_rgb)cv2.waitKey()cv2.destroyAllWindows()
           

匹配图像—一个对象

完整代码:

import cv2import numpy as npfrom matplotlib import pyplot as pltimg_rgb = cv2.imread('SourceIMG.jpeg')img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)template = cv2.imread('TemplateIMG.jpeg', 0)height, width = template.shape[::]res = cv2.matchTemplate(img_gray, template, cv2.TM_SQDIFF)plt.imshow(res, cmap='gray')min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)top_left = min_loc  #Change to max_loc for all except for TM_SQDIFFbottom_right = (top_left[0] + width, top_left[1] + height)cv2.rectangle(img_rgb, tp_left, bottom_right, (255, 0, 0), 2)  #White rectangle with thickness 2. cv2.imshow("Matched image", img_rgb)cv2.waitKey()cv2.destroyAllWindows()
           

检测多个对象-在给定阈值下

我们已经通过选择源图像和模板图像之间的最小差异来检测一个物体。通过定义阈值,我们可以检测与模板图像相似的所有对象。

为此,我将使用相同的源图像和用于一个对象检测的模板图像,其阈值概率大于0.5(您可以通过引用res数组来确定阈值)。我们只需要更改几行代码即可检测多个对象。

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
           

我在这里使用TM_CCOEFF_NORMED是因为我们需要获取最大值,而不是最小值。这意味着我们需要寻找多个对象而不是一个。

threshold = 0.5 #For TM_CCOEFF_NORMED, larger values means good fitloc = np.where( res >= threshold)
           

我们正在尝试查找所有大于阈值的位置值。loc将接收2个输出数组并将这些数组组合在一起,我们可以获得x,y坐标。

for pt in zip(*loc[::-1]):   cv2.rectangle(img_rgb, pt, (pt[0] + width, pt[1] + height), (255, 0, 0), 1)
           

我现在要在这里做的是代替多个地点。因此,对于所有这些位置,我们都需要绘制蓝色矩形。这就是我们需要设置的所有内容,让我们继续进行可视化处理。

opencv 模板匹配_使用模板匹配在Python上进行对象检测!(附代码)检测一个物体-最准确的物体检测多个对象-在给定阈值下

匹配的图像 一个对象

看起来很简单吧?但是如果我们使用机器学习或框架,则可以做到更高的准确性。