python实现的Iou与Giou代码

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

Jaccard index

后端开发标签