IoU 作为目标检测算法性能 mAP 计算的一个非常重要的函数。
IoU 的全称为交并比(Intersection over Union),通过这个名称我们大概可以猜到 IoU 的计算方法。IoU 计算的是 “预测的边框” 和 “真实的边框” 的交集和并集的比值。常见的两个框的交集情况有以下六种
iou的计算方式是:重叠面积/(总面积-重叠面积)
就按照yolo v2常用数据进行举例
假设重复部分面积为31*31,两个小格子面积都为32*32,那么iou=31*31/(32*32*2-31*31)。
如果需要进行人工计算的话,分别讨论六种情况是一件非常麻烦的事,因此在Torchvision中提供了相对应的工具计算iou
可以直接使用torchvision中的ops工具进行计算
工具中的计算方法和我们人工计算时有一点不同,不同点在于:我们手工计算的时候会进行一个加1操作,而工具不会,比如上面的情况在计算iou时,iou = 30*30/(31*31*2-30*30)。可以先使用自带的工具进行计算,如果效果不太理想,再进行手工操作。
在yolo v2中,需要先进行移动边框的操作。
假设黑色格子是图片上按照比例划分的小格子,红色的框则是我们标注的数据集的检测目标的区域,黑色的点是黑色框的中心,红色的点是红色框的中心, 红色的点一定在黑色框中。在进行iou计算时,需要将红色框的中心和黑色框的中心重合。如下所示
#传入标注的目标区域值,xmin,ymin,xmax,ymax
def move_gts(gts):
xmin,ymin,xmax,ymax = gts[:, 0], gts[:, 1], gts[:, 2], gts[:, 3]
#获取标注的目标框的中心比例
x, y = (xmin + xmax + 1) / 64, (ymin + ymax + 1) / 64
x, y = x - x.int(), y - y.int()
#获得偏移的x,y
shift_x, shift_y = (0.5 - x) * 32, (0.5 - y) * 32
#返回调整后的坐标
return torch.stack([xmin + shift_x, ymin + shift_y, xmax + shift_x, ymax + shift_y], dim=0).t()
可以使用下面的代码进行测试是否移动正确
gts = [
[-4, -4, 27, 27],
[36, 28, 67, 59],
[-4, 36, 27, 67],
[36, 36, 67, 67]
]
gts = torch.Tensor(gts)
print(move_gts(gts))
移动操作结束之后进行iou的计算操作,我们可以直接使用自带的工具进行计算
# 传入yolo格式的anchor和box格式的gts
def iou_mat(yolo_anchor, gts, w_n, cell_anchor_num=5):
batch_size, anchor_num, gt_num = gts.shape[0], yolo_anchor.shape[0], gts.shape[1]
#使用原来的方法,将yolo格式的anchor改成box类型
anchors = yolo2box(yolo_anchor,w_n,cell_anchor_num)
iou = torch.zeros(batch_size,anchor_num,gt_num)
for i in range(batch_size):
iou[i,:,:] = ops.box_iou(anchors,gts[i])
return iou
到此计算完毕