IoU 理论讲解

在计算机中,图像的坐标系是以左上角为原点,原点向右(x轴)和向下(y轴)分别作为两个坐标轴构成的,分别代表图像的宽度(width)和高度(height)。
Alt text

下面的图片中,红色框是标注好的框(Ground Truth),蓝色框是预测出来的。
Alt text

那么这两个框的交集就是下面黄色填充的区域:
Alt text

而两个框的并集,就是把两个框的区域合并(重叠部分+不重叠部分),就像下面这样:
Alt text

IoU就是交集区域面积与并集区域面积的比值,其计算公式如下:
$$IoU=\frac{交集}{并集}$$

假设已知每个框的左上角坐标和右下角坐标,具体地,用[x1,y1,x2,y2]代表蓝色框的坐标,用[xx1,yy1,xx2,yy2]代表红色框的坐标:
Alt text

现在来确定交集的左上角和右下角的坐标:

左上角坐标为$(max(x1,xx1),max(y1,yy1))$
右下角坐标为$(min(x2,xx2),min(y2,yy2))$

那么两者的交集区域面积为:
$$[min(y2,yy2)-max(y1,yy1)]*[min(x2,xx2)-max(x1,xx1)]$$

当两者无交集时,上式的乘法中有一项为负数,我们可以规定,只要出现负数,就取成0,即此时两者无交集,交集区域面积为0。下面这张图是无交集时的一种情况:
Alt text

PyTorch实现IoU

有了以上的理论讲解,代码实现起来就很简单了,直接上代码:

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 insert_over_union(boxes_preds,boxes_labels):
#预测框的左上角和右下角坐标
box1_x1=boxes_preds[...,0:1]
box1_y1=boxes_preds[...,1:2]
box1_x2=boxes_preds[...,2:3]
box1_y2=boxes_preds[...,3:4]#shape:[N,1]
#实际框的左上角和右下角坐标
box2_x1=boxes_labels[...,0:1]
box2_y1=boxes_labels[...,1:2]
box2_x2=boxes_labels[...,2:3]
box2_y2=boxes_labels[...,3:4]
#交集区域的左上角和右下角坐标
x1=torch.max(box1_x1,box2_x1)
y1=torch.max(box1_y1,box2_y1)
x2=torch.min(box1_x2,box2_x2)
y2=torch.min(box1_y2,box2_y2)
#计算交集区域的面积
intersection=(x2-x1).clamp(0)*(y2-y1).clamp(0)
#计算预测框区域的面积
box1_area=abs((box1_x2-box1_x1)*(box1_y1-box1_y2))
#计算实际框区域的面积
box2_area=abs((box2_x2-box2_x1)*(box2_y1-box2_y2))
#返回的结果即为iou
return intersection/(box1_area+box2_area-intersection+1e-6)

测试一下:
Alt text

参考:
https://www.youtube.com/watch?v=XXYG5ZWtjj0&t=503s