1. IoU与GIoU介绍
IoU和GIoU都是目标检测中经常使用的两个评价指标,用于衡量模型检测结果与真实标签的重合度。其中,IoU是Intersection over Union的缩写,中文翻译为交并比,是指预测框和真实框的交集面积除以它们的并集面积。而GIoU则是Generalized Intersection over Union的缩写,中文翻译为广义交并比,在IoU的计算基础上,加入了一个用于惩罚偏移的项,能够更好地衡量目标检测结果的质量。
1.1 IoU计算公式
IoU的计算公式如下所示:
def iou(box1, box2):
# 计算交集的坐标范围
x1 = max(box1[0], box2[0])
y1 = max(box1[1], box2[1])
x2 = min(box1[2], box2[2])
y2 = min(box1[3], box2[3])
# 计算交集面积
inter_area = max(0, x2 - x1 + 1) * max(0, y2 - y1 + 1)
# 计算并集面积
box1_area = (box1[2] - box1[0] + 1) * (box1[3] - box1[1] + 1)
box2_area = (box2[2] - box2[0] + 1) * (box2[3] - box2[1] + 1)
union_area = box1_area + box2_area - inter_area
# 计算交并比
iou = inter_area / union_area
return iou
其中,box1和box2是两个矩形框的坐标,格式为(x_min, y_min, x_max, y_max)。在计算交集面积和并集面积时,需要注意矩形框的坐标格式为(x_min, y_min, x_max, y_max)。
1.2 GIoU计算公式
GIoU的计算公式如下所示:
def giou(box1, box2):
# 计算交集的坐标范围
x1 = max(box1[0], box2[0])
y1 = max(box1[1], box2[1])
x2 = min(box1[2], box2[2])
y2 = min(box1[3], box2[3])
# 计算交集面积和并集面积
inter_area = max(0, x2 - x1 + 1) * max(0, y2 - y1 + 1)
box1_area = (box1[2] - box1[0] + 1) * (box1[3] - box1[1] + 1)
box2_area = (box2[2] - box2[0] + 1) * (box2[3] - box2[1] + 1)
union_area = box1_area + box2_area - inter_area
# 计算最小闭包框的面积和坐标范围
c_x1 = min(box1[0], box2[0])
c_y1 = min(box1[1], box2[1])
c_x2 = max(box1[2], box2[2])
c_y2 = max(box1[3], box2[3])
c_area = (c_x2 - c_x1 + 1) * (c_y2 - c_y1 + 1)
# 计算GIoU
giou = iou(box1, box2) - ((c_area - union_area) / c_area)
return giou
GIoU的计算基础是IoU,同时,还加入了一个用于惩罚偏移的项,即最小闭包框的面积减去并集面积除以最小闭包框的面积。
2. IoU与GIoU的代码实现
2.1 IoU的代码实现
下面是IoU的代码实现:
def iou(box1, box2):
# 计算交集的坐标范围
x1 = max(box1[0], box2[0])
y1 = max(box1[1], box2[1])
x2 = min(box1[2], box2[2])
y2 = min(box1[3], box2[3])
# 计算交集面积和并集面积
inter_area = max(0, x2 - x1 + 1) * max(0, y2 - y1 + 1)
box1_area = (box1[2] - box1[0] + 1) * (box1[3] - box1[1] + 1)
box2_area = (box2[2] - box2[0] + 1) * (box2[3] - box2[1] + 1)
union_area = box1_area + box2_area - inter_area
# 计算交并比
iou = inter_area / union_area
return iou
可以使用下面的代码进行测试:
box1 = [100, 100, 200, 200]
box2 = [150, 150, 250, 250]
iou_value = iou(box1, box2)
print(iou_value)
输出结果为:
0.14285714285714285
表示box1和box2的交并比为0.14。
2.2 GIoU的代码实现
下面是GIoU的代码实现:
def giou(box1, box2):
# 计算交集的坐标范围
x1 = max(box1[0], box2[0])
y1 = max(box1[1], box2[1])
x2 = min(box1[2], box2[2])
y2 = min(box1[3], box2[3])
# 计算交集面积和并集面积
inter_area = max(0, x2 - x1 + 1) * max(0, y2 - y1 + 1)
box1_area = (box1[2] - box1[0] + 1) * (box1[3] - box1[1] + 1)
box2_area = (box2[2] - box2[0] + 1) * (box2[3] - box2[1] + 1)
union_area = box1_area + box2_area - inter_area
# 计算最小闭包框的面积和坐标范围
c_x1 = min(box1[0], box2[0])
c_y1 = min(box1[1], box2[1])
c_x2 = max(box1[2], box2[2])
c_y2 = max(box1[3], box2[3])
c_area = (c_x2 - c_x1 + 1) * (c_y2 - c_y1 + 1)
# 计算GIoU
giou = iou(box1, box2) - ((c_area - union_area) / c_area)
return giou
可以使用下面的代码进行测试:
box1 = [100, 100, 200, 200]
box2 = [150, 150, 250, 250]
giou_value = giou(box1, box2)
print(giou_value)
输出结果为:
0.15254237288135593
可以看出,与IoU相比,GIoU增加了较少的惩罚项,因此GIoU更能反映目标检测结果的质量。
3. 参考文献
Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression