在图像中的对象周围绘制边界框 – 简单指南

计算机视觉和对象检测或识别系统使用边界框或矩形来识别图像或视频帧中的对象。

边界框出现在对象的边界中,将其与其他事物区分开来,这对于在连续视频帧中执行对象跟踪非常有用。

让我用一个简单的例子来解释一下。假设您想要跟踪一辆刚刚侵入您No Parking Zone花园的汽车的移动情况。你伸手去最近的交通站接车里的人。那里会发生什么?警员根据摄像机镜头分析该路线的交通情况,并使用计算机视觉为汽车绘制边界,以将其与其他汽车区分开来。现在,每当汽车移动到不同的地方时,警察都可以借助汽车周围的边界框来跟踪它。通过这个,我们可以追踪汽车的最近位置并采取必要的行动!

在本文中,我们将重点关注在二值图像中的多个对象周围绘制边界框。

什么是二值图像?

二值图像是只有两种颜色的图像,通常是黑色和白色。在图像处理中,二值图像每个像素仅包含一位,每个像素要么是 0,要么是 1。

先决条件

在继续绘制边界框之前,我们需要先安装 OpenCV 库。我们可以使用以下命令安装它。

pip install opencv-python

如果您在安装库时遇到任何问题,请参考这篇文章

为一个对象绘制边界框

让我们从简单的开始吧。在此示例中,我们将获取一张只有一个对象的二值图像,并为其绘制一个边界框。

出于参考目的,我们在本示例中使用的图像如下所示。

具有一个物体的图像

代码如下。

1
2
3
4
5
6
7
8
9
10
import cv2
from google.colab.patches import cv2_imshow
bimage = cv2.imread('/content/oneobject.png', cv2.IMREAD_GRAYSCALE)
contours, _ = cv2.findContours(bimage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
imagewithbbox = cv2.cvtColor(bimage, cv2.COLOR_GRAY2BGR)
for contour in contours:
    x, y, w, h = cv2.boundingRect(contour)
    cv2.rectangle(imagewithbbox, (x, y), (x + w, y + h), (0, 255, 0), 2
cv2.imwrite('/content/oneobjectrec.jpg', imagewithbbox)
cv2_imshow(imagewithbbox)

我们正在使用该行from google.colob.patches import...,因为在谷歌合作实验室中,该imshow()方法被禁用。如果您不使用 Google Colab 和任何其他笔记本或 IDE,则可以使用 import 导入该函数cv2.imshow()

我们安装的 OpenCV 库作为 cv2 导入到代码中。该文件cv2_imshow是从 Google colab 导入的,以避免出现任何错误。

我们想要为其绘制边界的二值图像存储在一个名为 image 的变量中。图像在 的帮助下读取imread,并在 的帮助下灰度化cv2.IMREAD_GRAYSCALE

用于findContours查找具有相同颜色或强度的所有连续点。cv2.CHAIN_APPROX_SIMPLE充当标志以确保矩形绘制在所需对象本身上。

在下一行中,我们创建图像的副本,以便可以在对象上绘制矩形。我们在轮廓上迭代 for 循环,以便识别所有具有轮廓的对象,并绘制边界。boundingRect函数用于获取矩形的所有坐标以及宽度和高度。代码(0,255,0)是用于根据RGB标度指定颜色的代码。在本例中,边界矩形的颜色为绿色。该组件2用于定义盒子的厚度。这里,它是 2 个像素。

在这里了解有关 imread() 的更多信息!

我们在 的帮助下保存图像imwrite并在 的帮助下显示imshow

输出如下。

围绕一个对象的边界框

同样,我们也可以绘制两个对象的边界框!让我们看一个为三个对象绘制边界框的复杂示例。

绘制三个对象的边界框

代码本质上是相同的。由于我们有一个 for 循环迭代图像的对象,因此对象的数量并不重要。在此代码中,我们将在对象周围绘制一个红色边界框。

我们要使用的图像的灵感来自哈利·波特。图像上有惠普的伤疤、死亡圣器和分院帽。

如下图所示。

原图

现在,如果我们运行该图像的代码,我们会得到一个带有三个对象边界框的图像。代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
import cv2
from google.colab.patches import cv2_imshow
binary_image = cv2.imread('/content/hporg.jpg', cv2.IMREAD_GRAYSCALE)
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
image_with_rectangles = binary_image.copy()
image_with_rectangles = cv2.cvtColor(image_with_rectangles, cv2.COLOR_GRAY2BGR)
 
for contour in contours:
    x, y, w, h = cv2.boundingRect(contour)
    cv2.rectangle(image_with_rectangles, (x, y), (x + w, y + h), (0,0,255), 6
cv2.imwrite('/content/hpboundrec.jpg', image_with_rectangles)
cv2_imshow(image_with_rectangles)

带边界框的图像如下所示。

三个带有噪声的物体周围的边界框

对象和边界框周围的小点可能是由于图像中存在可被检测为对象的小轮廓。这些通常称为噪声,可以通过设置轮廓阈值来消除。

代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
import cv2
from google.colab.patches import cv2_imshow
binary_image = cv2.imread('/content/hporg.jpg', cv2.IMREAD_GRAYSCALE)
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
min_contour_area = 100
image_with_rectangles = cv2.cvtColor(binary_image, cv2.COLOR_GRAY2BGR)
for contour in contours:
    contour_area = cv2.contourArea(contour)
    if contour_area >= min_contour_area:
        x, y, w, h = cv2.boundingRect(contour)
        cv2.rectangle(image_with_rectangles, (x, y), (x + w, y + h), (0, 0, 255), 6)
cv2.imwrite('/content/hpboundrec.jpg', image_with_rectangles)
cv2_imshow(image_with_rectangles)

观察第 5 行。我们为轮廓设置阈值为 100。我们只在轮廓大于100的对象周围绘制一个边界矩形。这样,我们就可以忽略轮廓区域较小的可能对象,

三个对象周围的边界框

结论

总之,我们通过示例了解了边界框在计算机视觉、图像检测、识别和对象跟踪中的重要性。我们查看了一个在二值图像中围绕单个对象绘制边界框的简单示例。

接下来,我们看一个包含三个对象的二值图像的示例。在这个例子中,我们遇到了噪音问题。所以我们增加了轮廓的阈值,这样小的噪音就会被忽略。

参考

OpenCV 文档

堆栈溢出