Appearance
目标检测与边界框
一、什么是目标检测
之前我们学的图像分类,都是假设图像里只有一个主要物体,只需要识别它的类别就行。但实际情况中,图像里往往有多个我们感兴趣的目标,比如一张图里有狗和猫,我们不仅想知道它们是狗和猫,还想知道它们在图里的具体位置,这种任务就叫目标检测。
目标检测的应用场景很多,比如无人驾驶里要识别车辆、行人的位置,机器人要检测感兴趣的目标,安防领域要检测异常目标,都需要用到目标检测。
二、什么是边界框
在目标检测里,我们用边界框(bounding box) 来表示目标的位置,它是一个矩形框,能把目标框在里面。边界框有两种常用的表示方法:
两角表示法:用矩形左上角的坐标 (x1, y1) 和右下角的坐标 (x2, y2) 来表示,比如 (x1, y1) 是左上角的点,(x2, y2) 是右下角的点。
中心宽高表示法:用矩形中心的坐标 (cx, cy),加上矩形的宽度 w 和高度 h 来表示。
三、边界框两种表示方法的转换
我们可以写两个函数,在这两种表示方法之间互相转换:
box_corner_to_center:把两角表示法转换成中心宽高表示法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 boxes2. 验证转换函数
我们可以用一个例子来验证这两个函数的正确性,比如我们有一个狗的边界框和一个猫的边界框:
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()这样就能看到图像里的狗和猫都被准确框住了。
五、小结
目标检测不仅要识别图像里的目标类别,还要知道目标的位置,位置用边界框表示。
边界框有两种表示方法:两角表示法(左上、右下坐标)和中心宽高表示法(中心坐标、宽高),可以互相转换。
我们可以用 matplotlib 把边界框画在图像上,验证边界框的准确性。
(注:文档部分内容可能由 AI 生成) 源地址