IoU
IoU就是我们所说的交并比,是目标检测中最常用的指标,在anchor-based的方法中,他的作用不仅用来确定正样本和负样本,还可以用来评价输出框(predict box)和ground-truth的距离。
可以说它可以反映预测检测框与真实检测框的检测效果。
还有一个很好的特性就是尺度不变性,也就是对尺度不敏感(scale invariant), 在regression任务中,判断predict box和gt的距离最直接的指标就是IoU。(满足非负性;同一性;对称性;三角不等性)
IoU的一种实现方式如下:
def intersection_over_union(box1, box2, wh=False):
"""
计算IoU(交并比)
:param box1: bounding box1
:param box2: bounding box2
:param wh: 坐标的格式是否为(x,y,w,h)
:return:计算结果
"""
if not wh:
xmin1, ymin1, xmax1, ymax1 = box1
xmin2, ymin2, xmax2, ymax2 = box2
else:
xmin1, ymin1 = int(box1[0] - box1[2] / 2.0), int(box1[1] - box1[3] / 2.0)
xmax1, ymax1 = int(box1[0] + box1[2] / 2.0), int(box1[1] + box1[3] / 2.0)
xmin2, ymin2 = int(box2[0] - box2[2] / 2.0), int(box2[1] - box2[3] / 2.0)
xmax2, ymax2 = int(box2[0] + box2[2] / 2.0), int(box2[1] + box2[3] / 2.0)
# 获取矩形框交集对应的左上角和右下角的坐标(intersection)
xx1 = max([xmin1, xmin2])
yy1 = max([ymin1, ymin2])
xx2 = min([xmax1, xmax2])
yy2 = min([ymax1, ymax2])
# 计算两个矩形框面积
area1 = (xmax1 - xmin1) * (ymax1 - ymin1)
area2 = (xmax2 - xmin2) * (ymax2 - ymin2)
inter_area = (max([0, xx2 - xx1])) * (max([0, yy2 - yy1])) # 计算交集面积
iou = inter_area / (area1 + area2 - inter_area + 1e-6) # 计算交并比
return iou
GIoU
在CVPR2019中,论文《Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression》
提出了GIoU的思想。由于IoU是比值的概念,对目标物体的scale是不敏感的。然而检测任务中的BBox的回归损失(MSE loss, l1-smooth loss等)优化和IoU优化不是完全等价的,而且 Ln 范数对物体的scale也比较敏感,IoU无法直接优化没有重叠的部分。
这篇论文提出可以直接把IoU设为回归的loss。
上面公式的意思是:先计算两个框的最小闭包区域面积A c A_c A c (通俗理解:同时包含了预测框和真实框的最小框的面积),再计算出IoU,再计算闭包区域中不属于两个框的区域占闭包区域的比重,最后用IoU减去这个比重得到GIoU。
GIoU的一种实现方式如下:
def g_iou(rec1, rec2):
"""
计算GIoU
:param rec1: bounding box1(xmin, ymin, xmax, ymax)格式
:param rec2: bounding box2(xmin, ymin, xmax, ymax)格式
:return: 计算结果
"""
# xmin, ymin, xmax, ymax格式
xmin1, ymin1, xmax1, ymax1 = rec1
xmin2, ymin2, xmax2, ymax2 = rec2
iou = intersection_over_union(rec1, rec2)
area_closure = (max(xmin1, xmax1, xmin2, xmax2) - min(xmin1, xmax1, xmin2, xmax2)) * (
max(ymin1, ymax1, ymin2, ymax2) - min(ymin1, ymax1, ymin2, ymax2))
area_1 = (xmax1 - xmin1) * (ymax1 - ymin1)
area_2 = (xmax2 - xmin2) * (ymax2 - ymin2)
sum_area = area_1 + area_2
w1 = xmax1 - xmin1 # 第一个矩形的宽
w2 = xmax2 - xmin2 # 第二个矩形的宽
h1 = ymax1 - ymin1
h2 = ymax2 - ymin2
w = min(xmin1, xmax1, xmin2, xmax2) + w1 + w2 - max(xmin1, xmax1, xmin2, xmax2) # 交叉部分的宽
h = min(ymin1, ymax1, ymin2, ymax2) + h1 + h2 - max(ymin1, ymax1, ymin2, ymax2) # 交叉部分的高
intersection_area = w * h # 交叉的面积
add_area = sum_area - intersection_area # 两矩形并集的面积
end_area = (area_closure - add_area) / area_closure # 闭包区域中不属于两个框的区域占闭包区域的比重
giou = iou - end_area
return giou
DIoU
DIoU要比GIou更加符合目标框回归的机制,将目标与anchor之间的距离,重叠率以及尺度都考虑进去,使得目标框回归变得更加稳定,不会像IoU和GIoU一样出现训练过程中发散等问题。
其中,b b b ,b g t b^{gt}b g t 分别代表了预测框和真实框的中心点,且 ρ \rho ρ代表的是计算两个中心点间的欧式距离。 c c c 代表的是能够同时包含预测框和真实框的最小闭包区域的对角线距离。
一种DIoU的实现方式:
def d_iou(rec1, rec2):
"""
计算DIoU
:param rec1: bounding box1(xmin, ymin, xmax, ymax)格式
:param rec2: bounding box2(xmin, ymin, xmax, ymax)格式
:return: 计算结果
"""
# xmin, ymin, xmax, ymax格式
xmin1, ymin1, xmax1, ymax1 = rec1
xmin2, ymin2, xmax2, ymax2 = rec2
iou = intersection_over_union(rec1, rec2)
# 中心点距离平方
center1 = ((xmin1 + xmax1) / 2, (ymin1 + ymax1) / 2)
center2 = ((xmin2 + xmax2) / 2, (ymin2 + ymax2) / 2)
d_center2 = (center1[0] - center2[0]) ** 2 + (center1[1] - center2[1]) ** 2
# 最小闭包矩形对角线长度平方
corner1 = (min(xmin1, xmax1, xmin2, xmax2), min(ymin1, ymax1, ymin2, ymax2))
corner2 = (max(xmin1, xmax1, xmin2, xmax2), max(ymin1, ymax1, ymin2, ymax2))
d_corner2 = (corner1[0] - corner2[0]) ** 2 + (corner1[1] + corner2[1]) ** 2
diou = iou - d_center2 / d_corner2
return diou
CIoU
考虑到bbox回归三要素中的长宽比还没被考虑到计算中,因此,进一步在DIoU的基础上提出了CIoU。其惩罚项如下面公式:
其中α \alpha α是权重函数
而v v v用来度量长宽比的相似性,定义为:
完整的 CIoU 损失函数定义:
一种CIoU的实现方式如下:
import numpy
def c_iou(rec1, rec2):
"""
计算CIoU
:param rec1: bounding box1(xmin, ymin, xmax, ymax)格式
:param rec2: bounding box2(xmin, ymin, xmax, ymax)格式
:return: 计算结果
"""
# xmin, ymin, xmax, ymax格式
xmin1, ymin1, xmax1, ymax1 = rec1
xmin2, ymin2, xmax2, ymax2 = rec2
iou = intersection_over_union(rec1, rec2)
# 中心点距离平方
center1 = ((xmin1 + xmax1) / 2, (ymin1 + ymax1) / 2)
center2 = ((xmin2 + xmax2) / 2, (ymin2 + ymax2) / 2)
d_center2 = (center1[0] - center2[0]) ** 2 + (center1[1] - center2[1]) ** 2
# 最小闭包矩形对角线长度平方
corner1 = (min(xmin1, xmax1, xmin2, xmax2), min(ymin1, ymax1, ymin2, ymax2))
corner2 = (max(xmin1, xmax1, xmin2, xmax2), max(ymin1, ymax1, ymin2, ymax2))
d_corner2 = (corner1[0] - corner2[0]) ** 2 + (corner1[1] + corner2[1]) ** 2
w1, h1 = xmax1 - xmin1, ymax1 - ymin1
w2, h2 = xmax2 - xmin2, ymax2 - ymin2
# 度量长宽比的参数
v = 4 * (np.arctan(w1 / h1) - np.arctan(w2 / h2)) ** 2 / (np.pi ** 2)
alpha = v / (1 - iou + v)
ciou = iou - d_center2 / d_corner2 - alpha * v
return ciou
Original: https://blog.csdn.net/Ray_awakepure/article/details/121594033
Author: Ray_awakepure
Title: IoU、GIoU、DIoU、CIoU计算方法
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/683166/
转载文章受原作者版权保护。转载请注明原作者出处!