1. IoU
1.1 原理
IoU(Intersection of Union),在目标检测中表示为真实框和预测框得交并比,定义如下:
I
o
U
=
交
集
A
并
集
B
IoU=\frac{交集A}{并集B}
IoU=并集B交集A
当真实框与预测框完全重合时,IoU为1,因此在目标检测中边框回归损失函数定义为:
L
o
s
s
I
o
U
=
1
−
I
o
U
Loss_{IoU}=1-IoU
LossIoU=1−IoU
1.2 代码实现
有关IoU得代码实现如下:
def IoU(bbox, prebox):
'''
bbox:真实框,坐标为(左下角坐标,右上交坐标),即(x_min1, y_min1, x_max1, y_max1)
prebox:预测框,坐标为(左下角坐标,右上交坐标),即(x_min2, y_min2, x_max2, y_max2)
'''
#计算交集部分左下角坐标x_l, y_l,右上角坐标x_r,y_r
x_l = max(bbox[0], prebox[0])
y_l = max(bbox[1], prebox[1])
x_r = min(bbox[2], prebox[2])
y_r = min(bbox[3], prebox[3])
bbox_area = (x_max1 - x_min1) * (y_max1 - y_min1) #真实框面积
prebox_area = (x_max2 - x_min2) * (y_max2 - y_min2) #预测框面积
inter_area = max(0, x_r - x_l) * max(0, y_r - y_l) #交集部分面积
iou = inter_area / (bbox_area + prebox_area - inter_area + 1e-6) #计算iou,其中1e-6为了防止分母为0
return iou
2. GIoU
2.1 原理
针对IoU计算存在两个问题:
①当预测框和真实框不相交时IoU恒为0,无法反应两个框之间距离得远近,并且此时IoU损失函数不可导,导致无法优化两个框不相交得情况
②当两个框大小面积相同,交集部分面积也相等时,IoU损失函数无法区分预测框和真实框不同的相交情况
对此GIoU引入最小外接矩形和差集,具体定义如下:
G
I
o
U
=
I
o
U
−
差
集
G
最
小
外
接
矩
形
C
GIoU = IoU - \frac{差集G}{最小外接矩形C}
GIoU=IoU−最小外接矩形C差集G
L
o
s
s
G
I
o
U
=
1
−
G
I
o
U
Loss_{GIoU} =1- GIoU
LossGIoU=1−GIoU
GIoU不仅关注了交集区域,同时还关注其他非重合区域,更好得反映预测框和真实框的重合度;IoU损失函数取值为[0, 1],而GIoU损失函数取值为[0, 2]之间
2.2 代码实现
有关GIoU得代码实现如下:
def GIoU(bbox, prebox):
'''
bbox:真实框,坐标为(左下角坐标,右上交坐标),即(x_min1, y_min1, x_max1, y_max1)
prebox:预测框,坐标为(左下角坐标,右上交坐标),即(x_min2, y_min2, x_max2, y_max2)
'''
#计算交集部分左下角坐标x_l, y_l,右上角坐标x_r,y_r
x_l = max(bbox[0], prebox[0])
y_l = max(bbox[1], prebox[1])
x_r = min(bbox[2], prebox[2])
y_r = min(bbox[3], prebox[3])
#计算最小外接矩形左下角坐标c_xl, c_yl,右上角坐标c_xr, c_yr
c_xl = min(bbox[0], prebox[0])
c_yl = min(bbox[1], prebox[1])
c_xr = max(bbox[2], prebox[2])
c_yr = max(bbox[3], prebox[3])
bbox_area = (x_max1 - x_min1) * (y_max1 - y_min1) #真实框面积
prebox_area = (x_max2 - x_min2) * (y_max2 - y_min2) #预测框面积
inter_area = max(0, x_r - x_l) * max(0, y_r - y_l) #交集部分面积
c_area = (c_xr - c_xl) * (c_yr - c_yl) #最小外接矩形面积
b_area = bbox_area + prebox_area - inter_area #并集面积
iou = inter_area / (b_area + 1e-6) #计算iou,其中1e-6为了防止分母为0
giou = iou - (c_area - b_area) / c_area #计算giou
return giou
3. DIoU
3.1 原理
对于GIoU,当预测框在真实框内部且预测框面积相等时,GIoU无法区分预测框和真实框的相对位置关系
对此DIoU引入中心距离,具体定义如下:
D
I
o
U
=
I
o
U
−
d
2
c
2
DIoU = IoU - \frac{d^2}{c^2}
DIoU=IoU−c2d2
L
o
s
s
D
I
o
U
=
1
−
D
I
o
U
Loss_{DIoU} =1- DIoU
LossDIoU=1−DIoU
其中
d
d
d为预测框和真实框中心点的距离,
c
c
c为最小外接矩形的对角线距离
通过最小化DIoU损失函数可以直接拉近预测框和真实框之间的距离,收敛速度快
3.2 代码实现
有关DIoU得代码实现如下:
def DIoU(bbox, prebox):
'''
bbox:真实框,坐标为(左下角坐标,右上交坐标),即(x_min1, y_min1, x_max1, y_max1)
prebox:预测框,坐标为(左下角坐标,右上交坐标),即(x_min2, y_min2, x_max2, y_max2)
'''
#计算交集部分左下角坐标x_l, y_l,右上角坐标x_r,y_r
x_l = max(bbox[0], prebox[0])
y_l = max(bbox[1], prebox[1])
x_r = min(bbox[2], prebox[2])
y_r = min(bbox[3], prebox[3])
#计算最小外接矩形左下角坐标c_xl, c_yl,右上角坐标c_xr, c_yr
c_xl = min(bbox[0], prebox[0])
c_yl = min(bbox[1], prebox[1])
c_xr = max(bbox[2], prebox[2])
c_yr = max(bbox[3], prebox[3])
bbox_area = (x_max1 - x_min1) * (y_max1 - y_min1) #真实框面积
prebox_area = (x_max2 - x_min2) * (y_max2 - y_min2) #预测框面积
inter_area = max(0, x_r - x_l) * max(0, y_r - y_l) #交集部分面积
iou = inter_area / (bbox_area + prebox_area - inter_area + 1e-6) #计算iou,其中1e-6为了防止分母为0
#计算真实框的中心坐标b_x, b_y,预测框的中心坐标p_x, p_y
p_x = (x_min2 + x_max2) / 2
p_y = (y_min2 + y_max2) / 2
b_x = (x_min1 + x_max1) / 2
b_y = (y_min1 + y_max1) / 2
c = (c_xr - c_xl) ** 2 + (c_yr - c_yl) ** 2 #对角线距离c
d = (p_x - b_x) ** 2 + (p_y - b_y) ** 2 #中心距离d
diou = iou - d / c #计算diou
return diou
4. CIoU
4.1 原理
对于DIoU,当预测框在真实框内部且预测框面积以及中心距离相等时,GIoU无法区分预测框和真实框的长宽比关系
对此CIoU引入长宽比因子,具体定义如下:
C
I
o
U
=
I
o
U
−
d
2
c
2
−
ν
2
(
1
−
I
o
U
)
+
ν
CIoU = IoU - \frac{d^2}{c^2} - \frac{\nu^2}{(1-IoU) + \nu}
CIoU=IoU−c2d2−(1−IoU)+νν2
L
o
s
s
C
I
o
U
=
1
−
C
I
o
U
Loss_{CIoU} =1- CIoU
LossCIoU=1−CIoU
其中
d
d
d为预测框和真实框中心点的距离,
c
c
c为最小外接矩形的对角线距离,
ν
\nu
ν是长宽比的相似性因子,定义如下:
ν
=
4
π
2
(
arctan
W
b
H
b
−
arctan
W
p
H
p
)
2
\nu = \frac{4}{\pi ^2}(\arctan \frac{W_b}{H_b} - \arctan \frac{W_p}{H_p})^2
ν=π24(arctanHbWb−arctanHpWp)2
其中
W
b
,
H
b
,
W
p
,
H
p
W_b,H_b,W_p,H_p
Wb,Hb,Wp,Hp分别为真实框宽、高以及预测框宽、高
4.2 代码实现
有关CIoU得代码实现如下:
def CIoU(bbox, prebox):
'''
bbox:真实框,坐标为(左下角坐标,右上交坐标),即(x_min1, y_min1, x_max1, y_max1)
prebox:预测框,坐标为(左下角坐标,右上交坐标),即(x_min2, y_min2, x_max2, y_max2)
'''
#计算交集部分左下角坐标x_l, y_l,右上角坐标x_r,y_r
x_l = max(bbox[0], prebox[0])
y_l = max(bbox[1], prebox[1])
x_r = min(bbox[2], prebox[2])
y_r = min(bbox[3], prebox[3])
#计算最小外接矩形左下角坐标c_xl, c_yl,右上角坐标c_xr, c_yr
c_xl = min(bbox[0], prebox[0])
c_yl = min(bbox[1], prebox[1])
c_xr = max(bbox[2], prebox[2])
c_yr = max(bbox[3], prebox[3])
bbox_area = (x_max1 - x_min1) * (y_max1 - y_min1) #真实框面积
prebox_area = (x_max2 - x_min2) * (y_max2 - y_min2) #预测框面积
inter_area = max(0, x_r - x_l) * max(0, y_r - y_l) #交集部分面积
iou = inter_area / (bbox_area + prebox_area - inter_area + 1e-6) #计算iou,其中1e-6为了防止分母为0
#计算真实框的中心坐标b_x, b_y,预测框的中心坐标p_x, p_y
p_x = (x_min2 + x_max2) / 2
p_y = (y_min2 + y_max2) / 2
b_x = (x_min1 + x_max1) / 2
b_y = (y_min1 + y_max1) / 2
c = (c_xr - c_xl) ** 2 + (c_yr - c_yl) ** 2 #对角线距离c
d = (p_x - b_x) ** 2 + (p_y - b_y) ** 2 #中心距离d
v = 4 * (math.atan((x_max1 - x_min1) / (y_max1 - y_min1)) - math.atan((x_max2 - x_min2) / (y_max2 - y_min2))) ** 2 / (math.pi ** 2) #计算长宽比因子
ciou = iou - d / c - v ** 2 / (1 - iou + v)#计算ciou
return ciou