常见iou解读与代码实现
一、✒️iou(intersection over union)
1.1 🔥iou原理
🚀交并比(iou, intersection over union)是一种计算不同图像相互重叠比例的算法,经常被用于深度学习领域的目标检测或语义分割任务中。
在我们得到模型输出的预测框位置后,也可以计算输出框与真实框(ground truth bound)之间的 iou,此时,这个框的取值范围为 0~1,0 表示两个框不相交,1 表示两个框正好重合。
1-iou 表示真实框与预测框之间的差异,如果用 1-iou,这时的取值范围还是 0~1,但是变成了 0 表示两个框重合,1 表示两个框不相交,这样也就符合了模型自动求极小值的要求。因此,可以使用1-iou来表示模型的损失函数(loss 函数)。
🎯iou 的定义如下:
✨直观来讲,iou 就是两个图形面积的交集和并集的比值
☀️ 优点
使用iou来计算预测框和目标框之间的损失有以下优点:
- 具有尺度不变性;
- 满足非负性;
- 满足对称性;
⚡️缺点
如果只使用iou交并比来计算目标框损失的话会有以下问题:
- 预测框与真实框之间不相交的时候,如果|a∩b|=0,iou=0,无法进行梯度计算;
- 相同的iou反映不出实际预测框与真实框之间的情况,虽然这三个框的iou值相等,但是预测框与真实框之间的相对位置却完全不一样;
也就是说,iou 初步满足了计算两个图像的几何图形相似度的要求,简单实现了图像重叠度的计算,但无法体现两个图形之间的距离以及图形长宽比的相似性。
1.2 🔥iou计算
上面介绍了iou原理,下面是iou简单计算的原理图,我们需要先计算出相交部分黄色的面积,然后再计算蓝框的面积与绿框围成面积的总和,然后计算两者的比值,如下:假设一个格子的面积是1,交集黄色部分的面积为2x2=4,蓝框与绿框围成面积总和为3x3+4x4-2x2=21,所以iou=4/21=0.19;
在代码中并不是采用上面的计算方法,而是使用坐标进行计算,如下图,矩形 ac 与矩形 bd 相交,它们的顶点a、b、c、d,分别是:a(0,0)、b(3,2)、c(6,8)、d(9,10)
📟此时 iou 的计算公式应为:
带入 a、b、c、d 四点的实际坐标后,可以得到:
1.3 📌iou代码实现
import numpy as np
def iou(box1, box2):
# 计算中间矩形的宽高
in_w = min(box1[2], box2[2]) - max(box1[0], box2[0])
in_h = min(box1[3], box2[3]) - max(box1[1], box2[1])
# 计算交集、并集面积
inter = 0 if in_w <= 0 or in_h <= 0 else in_h * in_w
union = (box2[2] - box2[0]) * (box2[3] - box2[1]) +\
(box1[2] - box1[0]) * (box1[3] - box1[1]) - inter
# 计算iou
iou = inter / union
return iou
if __name__ == "__main__":
box1 = [0, 0, 6, 8] # [左上角x坐标,左上角y坐标,右下角x坐标,右下角y坐标]
box2 = [3, 2, 9, 10]
print(iou(box1, box2))
运行结果:
0.23076923076923078
二、✒️giou(generalized iou)
2.1 giou原理
giou(generalized intersection over union) 相较于 iou 多了一个“generalized”,通过引入预测框和真实框的最小外接矩形来获取预测框、真实框在闭包区域中的比重,从而解决了两个目标没有交集时梯度为零的问题。
引入了最小封闭形状c
(可以把a,b
包含在内)
公式定义如下:
其中c
是两个框的最小外接矩形的面积。原有 iou 取值区间为 [0,1]
,而 giou 的取值区间为[-1,1]
;在两个图像完全重叠时iou=giou=1
,当两个图像不相交的时候iou=0,giou=-1
;
☀️优点
- 与iou只关注重叠区域不同,giou不仅关注重叠区域,还关注其他的非重合区域,能更好的反映两者的重合度;
- giou是一种iou的下界,取值范围[ − 1 , 1 ] 。在两者重合的时候取最大值1,在两者无交集且无限远的时候取最小值-1。因此,与iou相比,giou是一个比较好的距离度量指标,解决了不重叠情况下,也就是iou=0的情况,也能让训练继续进行下去。
⚡️缺点
但是目标框与预测框重叠的情况依旧无法判断:
2.2 🔥giou计算
上面我们已经计算出iou的值,这里还需要计算由ad构成c的面积,也就是9x10=90;由giou公式可以计算出:
2.3 📌giou代码实现
import numpy as np
def giou(box1, box2):
# 计算两个图像的最小外接矩形的面积
x1, y1, x2, y2 = box1
x3, y3, x4, y4 = box2
area_c = (max(x2, x4) - min(x1, x3)) * (max(y4, y2) - min(y3, y1))
# 计算中间矩形的宽高
in_w = min(box1[2], box2[2]) - max(box1[0], box2[0])
in_h = min(box1[3], box2[3]) - max(box1[1], box2[1])
# 计算交集、并集面积
inter = 0 if in_w <= 0 or in_h <= 0 else in_h * in_w
union = (box2[2] - box2[0]) * (box2[3] - box2[1]) + \
(box1[2] - box1[0]) * (box1[3] - box1[1]) - inter
# 计算iou
iou = inter / union
# 计算空白面积
blank_area = area_c - union
# 计算空白部分占比
blank_count = blank_area / area_c
giou = iou - blank_count
return giou
if __name__ == "__main__":
box1 = [0, 0, 6, 8]
box2 = [3, 2, 9, 10]
print(giou(box1, box2))
输出结果:
0.09743589743589745
三、✒️diou(distance-iou)
3.1 diou原理
giou 虽然解决了 iou 的一些问题,但是它并不能直接反映预测框与目标框之间的距离,diou(distance-iou)即可解决这个问题,它将两个框之间的重叠度、距离、尺度都考虑了进来,使得⽬标框回归变得更加稳定。diou的计算公式如下:
其中、b和bgt分别表示预测框与真实框的中心点坐标,p2(b,bgt)表示两个中心点的欧式距离(指在欧几里得空间中两点之间的距离),c 代表两个图像的最小外接矩形的对角线长度。
☀️优点
diou 相较于其他两种计算方法的优点是:
- diou 可直接最小化两个框之间的距离,所以作为损失函数时 loss 收敛更快。
- 与giou loss类似,diou loss在与⽬标框不重叠时,仍然可以为边界框提供移动⽅向。
- 在两个框完全上下排列或左右排列时,没有空白区域,此时 giou 几乎退化为了 iou,但是 diou 仍然有效。
- diou还可以替换普通的iou评价策略,应用于nms中,使得nms得到的结果更加合理和有效。
⚡️缺点
diou 在完善图像重叠度的计算功能的基础上,实现了对图形距离的考量,但仍无法对图形长宽比的相似性进行很好的表示。
3.2 diou计算
通过计算可得,中心点 b、中心点 bgt的坐标分别为:(3,4)、(6,6)
此时的 diou 计算公式为:
3.3 📌diou代码实现
import numpy as np
def calculate_diou(box1, box2):
# 计算两个图像的最小外接矩形的面积
x1, y1, x2, y2 = box1
x3, y3, x4, y4 = box2
area_c = (max(x2, x4) - min(x1, x3)) * (max(y4, y2) - min(y3, y1))
# 计算中间矩形的宽高
in_w = min(box1[2], box2[2]) - max(box1[0], box2[0])
in_h = min(box1[3], box2[3]) - max(box1[1], box2[1])
# 计算交集、并集面积
inter = 0 if in_w <= 0 or in_h <= 0 else in_h * in_w
union = (box2[2] - box2[0]) * (box2[3] - box2[1]) + \
(box1[2] - box1[0]) * (box1[3] - box1[1]) - inter
# 计算iou
iou = inter / union
# 计算中心点距离的平方
center_dist = np.square((x1 + x2) / 2 - (x3 + x4) / 2) + \
np.square((y1 + y2) / 2 - (y3 + y4) / 2)
# 计算对角线距离的平方
diagonal_dist = np.square(max(x1, x2, x3, x4) - min(x1, x2, x3, x4)) + \
np.square(max(y1, y2, y3, y4) - min(y1, y2, y3, y4))
# 计算diou
diou = iou - center_dist / diagonal_dist
return diou
box1 = [0, 0, 6, 8]
box2 = [3, 2, 9, 10]
print(calculate_diou(box1, box2))
输出结果:
0.1589460263493413
四、✒️ciou(complete-iou)
4.1 ciou原理
论⽂考虑到bbox回归三要素中的⻓宽⽐还没被考虑到计算中,为此,进⼀步在diou的基础上提出了ciou,同时考虑两个矩形的长宽比,也就是形状的相似性。所以ciou在diou的基础上添加了长宽比的惩罚项。
其中, α \alpha α 是权重函数, ν \nu ν而用来度量长宽比的相似性。计算公式为:
☀️优点
- 更准确的相似性度量:ciou考虑了边界框的中心点距离和对角线距离,因此可以更准确地衡量两个边界框之间的相似性,尤其是在目标形状和大小不规则的情况下。
- 鲁棒性更强:相比传统的iou,ciou对于目标形状和大小的变化更具有鲁棒性,能够更好地适应各种尺寸和形状的目标检测任务。
⚡️缺点
- 计算复杂度增加:ciou引入了额外的中心点距离和对角线距离的计算,因此相比传统的iou,计算复杂度有所增加,可能会增加一定的计算成本。
- 实现难度较高:ciou的计算方式相对复杂,需要对边界框的坐标进行更多的处理和计算,因此在实现上可能会相对困难一些,需要更多的技术和经验支持。
4.2 ciou计算
中心点 b、中心点 bgt的坐标分别为:(3,4)、(6,6),由此ciou计算公式如下:
4.3 📌ciou代码实现
import numpy as np
import iou
import diou
# box : [左上角x坐标,左上角y坐标,右下角x坐标,右下角y坐标]
box1 = [0, 0, 6, 8]
box2 = [3, 2, 9, 10]
# ciou
def ciou(box1, box2):
x1, y1, x2, y2 = box1
x3, y3, x4, y4 = box2
# box1的宽:box1_w,box1的高:box1_h,
box1_w = x2 - x1
box1_h = y2 - y1
# box2的宽:box2_w,box2的高:box2_h,
box2_w = x4 - x3
box2_h = y4 - y3
iou = iou(box1, box2)
diou = diou(box1, box2)
# v用来度量长宽比的相似性
v = (4 / (np.pi) ** 2) * (np.arctan(int(box2_w / box2_h)) - np.arctan(int(box1_w / box1_h)))
# α是权重函数
a = v / ((1 + iou) + v)
ciou = diou - a * v
return ciou
print(ciou(box1, box2))
输出结果:
0.1589460263493413
五、✒️eiou(efficient-iou)
5.1原理
eiou是在 ciou 的惩罚项基础上将预测框和真实框的纵横比的影响因子拆开,分别计算预测框和真实框的长和宽,并且加入focal聚焦优质的锚框,来解决 ciou 存在的问题。先前基于iou的损失,例如ciou和giou,不能有效地测量目标盒和锚点之间的差异,这导致bbr(边界框回归)模型优化的收敛速度慢,定位不准确。
针对上述问题,对ciou损失进行了修正,提出了一种更有效的iou损失,即eiou损失,定义如下:
其中wc和hc是覆盖两个盒子的最小围框的宽度和高度。也就是说,我们将损失函数分为三个部分:iou损失liou,距离损失ldis和方向损失lasp。这样,我们可以保留ciou损失的有效特点。同时,eiou损失直接使目标盒与锚盒宽度和高度的差值最小化,从而使收敛速度更快,定位效果更好。
5.2 代码实现
import numpy as np
def calculate_eiou(box1, box2):
# 计算嵌入向量(这里简化为使用中心点坐标作为嵌入向量)
center1 = np.array([(box1[0] + box1[2]) / 2, (box1[1] + box1[3]) / 2])
center2 = np.array([(box2[0] + box2[2]) / 2, (box2[1] + box2[3]) / 2])
# 计算嵌入向量之间的欧式距离
euclidean_distance = np.linalg.norm(center1 - center2)
# 计算目标框的面积
area_box1 = (box1[2] - box1[0]) * (box1[3] - box1[1])
area_box2 = (box2[2] - box2[0]) * (box2[3] - box2[1])
# 计算交集和并集的面积
intersection = max(0, min(box1[2], box2[2]) - max(box1[0], box2[0])) * \
max(0, min(box1[3], box2[3]) - max(box1[1], box2[1]))
union = area_box1 + area_box2 - intersection
# 计算eiou
eiou = 1 - intersection / union + euclidean_distance
return eiou
box1 = [0, 0, 6, 8]
box2 = [3, 2, 9, 10]
print(calculate_eiou(box1, box2))
输出结果
4.374782044694758
六、✒️focal-eiou
6.1 原理
- 总结了现有回归 loss 的问题:最重要的是没有直接优化需要优化的参数
- 提出了现有方法收敛速度较慢的问题,很多的低质量样本贡献了大部分的梯度,限制了框的回归
- 提出了 focal-eiou,平衡高质量样本和低质量样本对 loss 的贡献,也就是提升高质量(iou 大)样本的贡献,抑制低质量(iou 小)样本的贡献
简单的方法不能直接适用于基于iou的损失。因此,我们最后提出focal-eiou损失来改善eiou损失的性能。使用iou的值来重新加权eiou损失,并获得focal-eiou损失,通过对难以分类的样本进行更加重视的损失函数设计,从而进一步提高目标检测算法的性能。如下所示:
其中 γ \gamma γ为控制异常值抑制程度的参数。该损失中的focal与传统的focal loss有一定的区别,传统的focal loss针对越困难的样本损失越大,起到的是困难样本挖掘的作用;而根据上述公式:iou越高的损失越大,相当于加权作用,给越好的回归目标一个越大的损失,有助于提高回归精度。
☀️优点
- eiou在ciou的基础上分别计算宽高的差异值取代了纵横比,宽高损失直接使预测框与真实框的宽度和高度之差最小,使得收敛速度更快;
- 在处理难以分类的样本时表现更好,能够进一步提高目标检测算法的鲁棒性和准确性。
⚡️缺点
在一般情况下可能会增加一定的计算复杂度,同时需要更多的参数调优和训练策略设计。
📌6.2 代码实现
import numpy as np
def calculate_focal_eiou(box1, box2, alpha=0.25, gamma=2):
# 计算嵌入向量(这里简化为使用中心点坐标作为嵌入向量)
center1 = np.array([(box1[0] + box1[2]) / 2, (box1[1] + box1[3]) / 2])
center2 = np.array([(box2[0] + box2[2]) / 2, (box2[1] + box2[3]) / 2])
# 计算嵌入向量之间的欧式距离
euclidean_distance = np.linalg.norm(center1 - center2)
# 计算目标框的面积
area_box1 = (box1[2] - box1[0]) * (box1[3] - box1[1])
area_box2 = (box2[2] - box2[0]) * (box2[3] - box2[1])
# 计算交集和并集的面积
intersection = max(0, min(box1[2], box2[2]) - max(box1[0], box2[0])) * \
max(0, min(box1[3], box2[3]) - max(box1[1], box2[1]))
union = area_box1 + area_box2 - intersection
# 计算focal loss
iou = intersection / union
focal_loss = -alpha * (1 - iou) ** gamma
# 计算focal-eiou
focal_eiou = 1 - iou + euclidean_distance + focal_loss
return focal_eiou
box1 = [0, 0, 6, 8]
box2 = [3, 2, 9, 10]
print(calculate_focal_eiou(box1, box2))
输出结果:
4.2268530506119175
七、✒️siou(soft intersection over union)
7.1原理
该论文中提出了一种新的损失函数 siou,其中考虑到所需回归之间的向量角度,重新定义了惩罚指标。应用于传统的神经网络和数据集,表明 siou 提高了训练的速度和推理的准确性。
在许多模拟和测试中揭示了所提出的损失函数的有效性。特别是,将 siou 应用于 coco-train/coco-val 与其他损失函数相比,提高了 +2.4% (map@0.5:0.95) 和 +3.6%(map@0.5)。
siou损失函数由4个cost代价函数组成:
- angle cost
- distance cost
- shape cost
- iou cost
➤ angle cost(角度代价)
如果
α
\alpha
α<=45°的时候,需要先最小化
α
\alpha
α;如果
α
\alpha
α>45°,则需要最小化
β
\beta
β=90°-
α
\alpha
α,从公式化简之后的结果可以得出,如果预测框和真实框沿着x轴或者y轴对齐的时候,此时
⋀
\bigwedge
⋀=0,如果中心点角度为45°的时候,此时
⋀
\bigwedge
⋀=1;
论文中计算公式:
λ
=
1
−
2
∗
sin
2
(
arcsin
(
x
)
−
π
4
)
\lambda=1-2 * \sin ^2\left(\arcsin (x)-\frac{\pi}{4}\right)
λ=1−2∗sin2(arcsin(x)−4π)
x = c h σ = sin ( α ) σ = ( b c x g t − b c x ) 2 + ( b c y g t − b c y ) 2 c h = max ( b c y g t , b c y ) − min ( b c y g t , b c y ) \begin{gathered}x=\frac{c_h}{\sigma}=\sin (\alpha) \\ \sigma=\sqrt{\left(b_{c_x}^{g t}-b_{c_x}\right)^2+\left(b_{c_y}^{g t}-b_{c_y}\right)^2} \\ c_h=\max \left(b_{c_y}^{g t}, b_{c_y}\right)-\min \left(b_{c_y}^{g t}, b_{c_y}\right)\end{gathered} x=σch=sin(α)σ=(bcxgt−bcx)2+(bcygt−bcy)2ch=max(bcygt,bcy)−min(bcygt,bcy)
可以将x和 α \alpha α的值带入公式进行化简,其中 c h c_h ch 为真实框和预测框中心点的高度差, σ \sigma σ 为真实框和预测框中心点的距离。
λ = 1 − 2 ∗ sin 2 ( arcsin ( c h σ ) − π 4 ) = 1 − 2 ∗ sin 2 ( α − π 4 ) = cos 2 ( α − π 4 ) − sin 2 ( α − π 4 ) = cos ( 2 α − π 2 ) = sin ( 2 α ) \begin{aligned} & \lambda=1-2 * \sin ^2\left(\arcsin \left(\frac{c_h}{\sigma}\right)-\frac{\pi}{4}\right) \\ & =1-2 * \sin ^2\left(\alpha-\frac{\pi}{4}\right) \\ & =\cos ^2\left(\alpha-\frac{\pi}{4}\right)-\sin ^2\left(\alpha-\frac{\pi}{4}\right) \\ & =\cos \left(2 \alpha-\frac{\pi}{2}\right) \\ & =\sin (2 \alpha)\end{aligned} λ=1−2∗sin2(arcsin(σch)−4π)=1−2∗sin2(α−4π)=cos2(α−4π)−sin2(α−4π)=cos(2α−2π)=sin(2α)
➤ distance cost(距离成本)
真实值边界框与边界框预测值之间距离的计算方案。
根据上面定义的角度成本重新定义距离成本:
δ
=
∑
t
=
x
,
y
(
1
−
e
−
γ
ρ
t
)
\delta=\sum_{t=x, y}\left(1-e^{-\gamma \rho_t}\right)
δ=t=x,y∑(1−e−γρt)
where
ρ
x
=
(
b
c
x
g
t
−
b
c
x
c
w
)
2
,
ρ
y
=
(
b
c
y
g
t
−
b
c
y
c
h
)
2
,
γ
=
2
−
λ
\rho_x=\left(\frac{b_{c_x}^{g t}-b_{c_x}}{c_w}\right)^2, \rho_y=\left(\frac{b_{c_y}^{g t}-b_{c_y}}{c_h}\right)^2, \gamma=2-\lambda
ρx=(cwbcxgt−bcx)2,ρy=(chbcygt−bcy)2,γ=2−λ
当 α → 0 \alpha \rightarrow 0 α→0,距离成本的贡献大大减少.与之相反 α \alpha α 越接近 π 4 \frac{\pi}{4} 4π, δ \delta δ就越大,随着角度的增加,问题变得更加困难。 所以,随着角度的增加 γ \gamma γ 的时间优先于距离值。当 α → 0 \alpha \rightarrow 0 α→0,距离成本将变为常规成本。
➤ shape cost(形状成本)
形状成本定义为:
ω
=
∑
t
=
w
,
h
(
1
−
e
−
ω
t
)
θ
\omega=\sum_{t=w, h}\left(1-e^{-\omega_t}\right)^\theta
ω=t=w,h∑(1−e−ωt)θ
其中:
ω
w
=
∣
w
−
w
g
t
∣
max
(
w
,
w
g
t
)
,
ω
h
=
∣
h
−
h
g
t
∣
max
(
h
,
h
g
t
)
\omega_w=\frac{\left|w-w^{g t}\right|}{\max \left(w, w^{g t}\right)}, \omega_h=\frac{\left|h-h^{g t}\right|}{\max \left(h, h^{g t}\right)}
ωw=max(w,wgt)∣w−wgt∣,ωh=max(h,hgt)∣h−hgt∣
𝜃 的值定义了形状的成本,并且其值对于每个数据集都是唯一的。 𝜃 的值是这个方程中非常重要的一项,它控制着对形状成本的关注程度。如果𝜃的值设置为1,它将立即优化形状,从而损害形状的自由运动。为了计算 𝜃 的值,对每个数据集使用遗传算法,实验上 𝜃 的值接近 4,作者为此参数定义的范围是从 2 到 6。
➤ siou最后的回归损失为:
l
b
o
x
=
1
−
i
o
u
+
δ
+
ω
2
l_{b o x}=1-i o u+\frac{\delta+\omega}{2}
lbox=1−iou+2δ+ω
八、✒️wise-iou
关于wise-iou的详细介绍可以观看这篇论文:wise-iou 作者导读:基于动态非单调聚焦机制的边界框损失
wiou主要有以下几点优势:
- 相对面积加权
wiou损失函数的计算中引入了交集与并集的比值,从而对不同大小的目标框进行了相对面积加权。这样可以避免小目标对损失函数的影响过大,提升了对小目标的检测效果。 - 解决类别不平衡问题
在目标检测任务中,经常会遇到类别不平衡的情况,即某些类别的目标数量明显少于其他类别。wiou损失函数通过引入权重因子,可以对不同类别的目标进行不同程度的加权,从而解决了类别不平衡问题。 - 高度可定制化
wiou损失函数的计算中,可以根据实际需求调整交集和并集的权重因子,从而对不同任务和数据集进行高度定制化的适配。这使得wiou损失函数在实际应用中具有更广泛的适用性。
发表评论