Skip to content

目标检测与边界框

一、什么是目标检测

之前我们学的图像分类,都是假设图像里只有一个主要物体,只需要识别它的类别就行。但实际情况中,图像里往往有多个我们感兴趣的目标,比如一张图里有狗和猫,我们不仅想知道它们是狗和猫,还想知道它们在图里的具体位置,这种任务就叫目标检测

alt text

目标检测的应用场景很多,比如无人驾驶里要识别车辆、行人的位置,机器人要检测感兴趣的目标,安防领域要检测异常目标,都需要用到目标检测。

二、什么是边界框

在目标检测里,我们用边界框(bounding box) 来表示目标的位置,它是一个矩形框,能把目标框在里面。边界框有两种常用的表示方法:

  1. 两角表示法:用矩形左上角的坐标 (x1, y1) 和右下角的坐标 (x2, y2) 来表示,比如 (x1, y1) 是左上角的点,(x2, y2) 是右下角的点。

  2. 中心宽高表示法:用矩形中心的坐标 (cx, cy),加上矩形的宽度 w 和高度 h 来表示。

alt text

三、边界框两种表示方法的转换

我们可以写两个函数,在这两种表示方法之间互相转换:

  1. box_corner_to_center:把两角表示法转换成中心宽高表示法

  2. box_center_to_corner:把中心宽高表示法转换成两角表示法

1. 转换函数的实现(PyTorch 版)

python
import torch
from d2l import torch as d2l

# 从(左上,右下)转换到(中间,宽度,高度)
def box_corner_to_center(boxes):
    x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]
    cx = (x1 + x2) / 2  # 中心x坐标
    cy = (y1 + y2) / 2  # 中心y坐标
    w = x2 - x1         # 宽度
    h = y2 - y1         # 高度
    boxes = torch.stack((cx, cy, w, h), axis=-1)
    return boxes

# 从(中间,宽度,高度)转换到(左上,右下)
def box_center_to_corner(boxes):
    cx, cy, w, h = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]
    x1 = cx - 0.5 * w  # 左上角x坐标
    y1 = cy - 0.5 * h  # 左上角y坐标
    x2 = cx + 0.5 * w  # 右下角x坐标
    y2 = cy + 0.5 * h  # 右下角y坐标
    boxes = torch.stack((x1, y1, x2, y2), axis=-1)
    return boxes

2. 验证转换函数

我们可以用一个例子来验证这两个函数的正确性,比如我们有一个狗的边界框和一个猫的边界框:

python
# 狗的边界框(左上x, 左上y, 右下x, 右下y)
dog_bbox = [60.0, 45.0, 378.0, 516.0]
# 猫的边界框(左上x, 左上y, 右下x, 右下y)
cat_bbox = [400.0, 112.0, 655.0, 493.0]

# 把两个边界框转换成张量
boxes = torch.tensor((dog_bbox, cat_bbox))
# 先把两角表示转换成中心宽高表示,再转换回两角表示,看看是不是和原来的一样
print(box_center_to_corner(box_corner_to_center(boxes)) == boxes)

运行结果会是:

Plain
tensor([[True, True, True, True],
        [True, True, True, True]])

说明转换是正确的。

四、在图像上画边界框

我们可以用 matplotlib 把边界框画在图像上,看看是不是准确框住了目标。首先定义一个辅助函数,把边界框转换成 matplotlib 能识别的格式:

python
def bbox_to_rect(bbox, color):
    # 把(左上x, 左上y, 右下x, 右下y)转换成matplotlib的格式:((左上x, 左上y), 宽, 高)
    return d2l.plt.Rectangle(
        xy=(bbox[0], bbox[1]),
        width=bbox[2] - bbox[0],
        height=bbox[3] - bbox[1],
        fill=False,  # 不填充
        edgecolor=color,  # 边框颜色
        linewidth=2  # 边框宽度
    )

然后加载图像,把边界框画上去:

python
# 加载图像
img = d2l.plt.imread('../img/catdog.jpg')
# 显示图像
fig = d2l.plt.imshow(img)
# 加上狗的边界框(蓝色)
fig.axes.add_patch(bbox_to_rect(dog_bbox, 'blue'))
# 加上猫的边界框(红色)
fig.axes.add_patch(bbox_to_rect(cat_bbox, 'red'))
# 显示图像
d2l.plt.show()

这样就能看到图像里的狗和猫都被准确框住了。

五、小结

  1. 目标检测不仅要识别图像里的目标类别,还要知道目标的位置,位置用边界框表示。

  2. 边界框有两种表示方法:两角表示法(左上、右下坐标)和中心宽高表示法(中心坐标、宽高),可以互相转换。

  3. 我们可以用 matplotlib 把边界框画在图像上,验证边界框的准确性。

(注:文档部分内容可能由 AI 生成) 源地址

京ICP备2024093538号-1