前言
记《动手学深度学习》组队学习第三次打卡
打卡内容
计算机视觉——目标检测基础(一)
简介
在图像分类任务中(图像分类的内容会在后续的博客中更新),假设图像中只有一个主体目标,并关注计算机如何判别该目标的类别。然而,在很多时候,图像里有多个感兴趣的目标,我们不仅想知道它们的类别,还想了解它们在图像中的具体位置。在计算机视觉里,将这类任务成为目标检测(Object Detection)或物体检测。
目标检测在多个领域中被广泛应用,例如,在无人驾驶中,需要通过识别拍摄到的视频图像里的车辆、行人、道路和障碍物的位置来规划前进路线;机器人也尝尝通过该任务来检测感兴趣的目标;安防领域则需要检测异常目标,如歹徒或炸弹。
在接下来的几节里,将介绍目标检测基础知识。
边界框
在目标检测里,通常使用边界框(Bounding Box)来描述目标的位置。边界框是一个矩形框,可以由矩形左上角的
x
x
x和
y
y
y轴坐标与右下角的
x
x
x和
y
y
y轴坐标确定。
例如,在下面这张图中:
# bbox 是bounding box的缩写
dog_bbox = [60, 45, 378, 516]
cat_bbox = [400, 112, 655, 493]
我们可以在图中将边界框画出来,以检查是否准确。画之前,需定义一个辅助函数bbox_to_rect
,将边界框表示成matplotlib的边界框格式。
def bbox_to_rect(bbox, color):
# 将边界框(左上x, 左上y, 右下x, 右下y)转换成matplotlib格式:
# ((左上x, 左上y), 宽, 高)
xy = (bbox[0], bbox[1])
width = bbox[2]-bbox[0]
height = bbox[3]-bbox[1]
return plt.Rectangle(xy=xy, width=width, height=height,
fill=False, edgecolor=color, linewidth=2)
fig = plt.imshow(img)
fig.axes.add_patch(bbox_to_rect(dog_bbox), 'blue')
fig.axes.add_patch(bbox_to_rect(cat_bbox), 'red')
锚框
目标检测算法通常会在输入图像中采集大量的区域,然后判断这些区域中是否包含感兴趣的目标,并调整区域边缘从而更准确地预测目标的真实边界框(Ground-Truth Bounding Box)。不同的模型使用的区域采样方法可能不同。这里我们介绍其中的一种方法:它以每个像素为中心生成多个大小和宽高比(aspect ratio)不同的边界框。这些边界框被称为锚框(anchor box)。我们将在后续博客中更新基于锚框实践目标检测,本文主要阐述必须要先弄明白的基础知识
假设输入图像高为
h
h
h,宽为
w
w
w。我们分别以图像的每个像素为中心生成不同形状的锚框。设大小为
s
∈
(
0
,
1
]
s∈(0,1]
s∈(0,1]且宽高比为
r
>
0
r>0
r>0,那么锚框的宽和高将分别为
w
s
r
ws\sqrt r
wsr和
h
s
/
r
hs/\sqrt r
hs/r。当中心位置给定时,已知宽和高的锚框是确定的。
下面我们分别设定好一组大小
s
1
,
…
,
s
n
s_1,…,s_n
s1,…,sn和一组宽高比
r
1
,
…
,
r
m
r_1,…,r_m
r1,…,rm。如果以每个像素为中心时使用所有的大小与宽高比的组合,输入图像将一共得到
w
h
n
m
whnm
whnm个锚框。虽然这些锚框可能覆盖了所有的真实边界框,但计算复杂度容易过高。因此,我们通常只对包含
s
1
s_1
s1或
r
1
r_1
r1的大小与宽高比的组合感兴趣,即
(
s
1
,
r
1
)
,
(
s
1
,
r
2
)
,
…
,
(
s
1
,
r
m
)
,
(
s
2
,
r
1
)
,
(
s
3
,
r
1
)
,
…
,
(
s
n
,
r
1
)
(s_1,r_1),(s_1,r_2),…,(s_1,r_m),(s_2,r_1),(s_3,r_1),…,(s_n,r_1)
(s1,r1),(s1,r2),…,(s1,rm),(s2,r1),(s3,r1),…,(sn,r1)
也就是说,以相同像素为中心的锚框的数量为
n
+
m
−
1
n+m−1
n+m−1。对于整个输入图像,我们将一共生成
w
h
(
n
+
m
−
1
)
wh(n+m−1)
wh(n+m−1)个锚框,锚框的数量将大大减少。
此处重点解释一下锚框大小 s s s的含义,以便更好地理解式子 w s r ws\sqrt r wsr和 h s / r hs/\sqrt r hs/r。
对于原始图像或者卷积过程中的特征图(feature map),有着各自的实际大小,记为宽
w
w
w,高
h
h
h。(高对应
y
y
y轴,宽对应
x
x
x轴)
在对各像素点上计算锚框大小时(以图像的每个像素为中心生成不同形状的锚框),将宽和高分别归一化为1,如,原本像素点坐标为(200,245),归一化后变成(
200
/
w
200/w
200/w,
245
/
h
245/h
245/h)。
注意,归一化后将不保持图像原本的宽高比(原本宽高比为
w
/
h
w/h
w/h);归一化后的宽高比为1,宽方向上被划分成
w
w
w等分;高方向上被划分成
h
h
h等分。
这只是在计算工程中的状态,图像本身的尺寸当然是不会变成1*1的。
在归一化后的基础上,再去计算锚框。锚框自身也有宽高,记为宽
s
s
1
ss_1
ss1,高
s
s
2
ss_2
ss2;宽高比
r
r
r是基于
s
s
1
ss_1
ss1、
s
s
2
ss_2
ss2计算的,为
s
s
1
/
s
s
2
ss_1/ss_2
ss1/ss2。(锚框在图像中显示的真实宽高应为
s
s
1
∗
w
ss_1*w
ss1∗w和
s
s
2
∗
h
ss_2*h
ss2∗h)
当宽高比
r
=
1
r=1
r=1时,显然,
s
s
1
=
s
s
2
ss_1=ss_2
ss1=ss2,此时的
s
s
1
ss_1
ss1和
s
s
2
ss_2
ss2与锚框的尺寸
s
s
s一致;宽高比
r
≠
1
r\ne 1
r=1,显然,
s
s
1
ss_1
ss1不等于
s
s
2
ss_2
ss2,但应满足
s
2
=
s
s
1
∗
s
s
2
s^2 = ss_1 * ss_2
s2=ss1∗ss2。
在上述条件下,便能在给定
s
s
s、
r
r
r时(因为我们的输入只有
s
s
s、
r
r
r),计算得到
s
s
1
ss_1
ss1和
s
s
2
ss_2
ss2。
小结
目标检测基础(一)暂时更新上述内容,一定要掌握对锚框的理解以及其计算方法,这样写代码的时候才不容易混乱。