Introduction

在目标检测中,我们需要定位出目标的位置,而我们的算法不可能百分百跟人工标注的数据完全匹配,因此需要一种衡量目标定位精度的标准。

IoU(Intersection over Union)是一种常见的用于衡量目标定位精度的标准,可以理解为重叠度,是一种简单的测量标准,只要是在输出中得出一个预测范围(bounding box)的任务都可以用IoU来进行测量。

IoU

如上图所示,ground-truth和predicted的存在误差,绿色框是人为标记的正确结果,红色框是算法预测出来的结果,IoU要做的就是在这两个结果中测量算法的准确度,它定义了两个bounding box的重叠度 ,如下图所示:

IoU

IoU=ABAB=ABA+BABIoU = \frac {A\bigcap B}{A\bigcup B}=\frac{A\bigcap B}{A+B-A\bigcap B}

就是矩形框A、B的重叠面积,占 ABA\bigcup B 的面积比例。

一般来说,IoU>0.5IoU>0.5 就可以被认为一个不错的结果,IoU>0.7IoU>0.7 结果就非常不错了,可以参见下图

IoU examples

实现

因为IoU的思想很简单,Python实现可以参考[1]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def bb_intersection_over_union(boxA, boxB):
# determine the (x, y)-coordinates of the intersection rectangle
xA = max(boxA[0], boxB[0])
yA = max(boxA[1], boxB[1])
xB = min(boxA[2], boxB[2])
yB = min(boxA[3], boxB[3])

# compute the area of intersection rectangle
interArea = (xB - xA + 1) * (yB - yA + 1)

# compute the area of both the prediction and ground-truth
# rectangles
boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)
boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)

# compute the intersection over union by taking the intersection
# area and dividing it by the sum of prediction + ground-truth
# areas - the interesection area
iou = interArea / float(boxAArea + boxBArea - interArea)

# return the intersection over union value
return iou

在Pytorch中,可以写成如下形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import torch 
def bbox_iou(box1, box2):
"""
Returns the IoU of two bounding boxes
"""
#Get the coordinates of bounding boxes
b1_x1, b1_y1, b1_x2, b1_y2 = box1[:,0], box1[:,1], box1[:,2], box1[:,3]
b2_x1, b2_y1, b2_x2, b2_y2 = box2[:,0], box2[:,1], box2[:,2], box2[:,3]

#get the corrdinates of the intersection rectangle
inter_rect_x1 = torch.max(b1_x1, b2_x1)
inter_rect_y1 = torch.max(b1_y1, b2_y1)
inter_rect_x2 = torch.min(b1_x2, b2_x2)
inter_rect_y2 = torch.min(b1_y2, b2_y2)

#Intersection area
inter_area = torch.clamp(inter_rect_x2 - inter_rect_x1 + 1, min=0) * torch.clamp(inter_rect_y2 - inter_rect_y1 + 1, min=0)

#Union Area
b1_area = (b1_x2 - b1_x1 + 1)*(b1_y2 - b1_y1 + 1)
b2_area = (b2_x2 - b2_x1 + 1)*(b2_y2 - b2_y1 + 1)

iou = inter_area / (b1_area + b2_area - inter_area)

return iou

Reference

[1]Intersection over Union (IoU) for object detection