【算法】Python实现IoU计算

1,004 阅读2分钟

IoU的计算是目标检测基础中的基础,用于两个矩阵的交并比。可以用于预测b-box和groundtruth之间的差异。以下是总结的一些网上的博文。

image.png

IOU = 绿色面积/(蓝色面积+绿色面积+橙色面积)

平行于坐标轴的矩形框

输入:两个矩形框由四个坐标表示

rec: (y0, x0, y1, x1), which reflects (top, left, bottom, right)

输出:IoU结果

对于矩形框与坐标轴平行的情况,计算还是非常简单的:

def compute_iou(rec1, rec2):
    """
    computing IoU
    :param rec1: (y0, x0, y1, x1)
    :param rec2: (y0, x0, y1, x1)
    :return: scala value of IoU
    """
    # computing area of each rectangles
    S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1])
    S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1])

    # computing the sum_area
    sum_area = S_rec1 + S_rec2

    # find the each edge of intersect rectangle
    left_line = max(rec1[1], rec2[1])
    right_line = min(rec1[3], rec2[3])
    top_line = max(rec1[0], rec2[0])
    bottom_line = min(rec1[2], rec2[2])

    # judge if there is an intersect
    if left_line >= right_line or top_line >= bottom_line:
        return 0
    else:
        intersect = (right_line - left_line) * (bottom_line - top_line)
        return (intersect / (sum_area - intersect)) * 1.0

倾斜矩形框

使用Python中的Shapely模块进行倾斜矩形框的计算(待完善)

回归损失函数

IoU loss可以表示为:LIoU=1IoU:L_{IoU}=1-IoU

GIoU

IoU简单但有明显缺点,GIoU在IoU的基础上做了一些改进:

  1. 当两个b-box没有交集时IoU loss=1,无法反应出检测框与groundtruth之间的距离。只要两个框没有交集,IoU loss恒等于1,无论朝哪个方向优化,IoU loss都不会下降,失去指导性。

  2. IoU并不能反应两个b-box之间的贴合度。

image.png

GIoU在IoU的基础上找到全局框C,把两个b-box装进去。额外面积C_。此时: GIOU = IOU - C_/C GIoU loss可以表示为:LGIoU=1GIoU:L_{GIoU}=1-GIoU

两个框没有交集的情况下:

image.png

GIOU会随两个框之间的距离变化而变化,反应到loss上,从而指导预测框的移动方向。

DIoU

在GIoU的基础上进一步强调了距离的重要性。

公式在这里: LDIoU=1IoU+ρ2(b,bgt)c2L_{DIoU}=1-IoU+\frac{\rho ^2\left( \boldsymbol{b},\boldsymbol{b}^{\boldsymbol{gt}} \right)}{c^2}

和GIoU loss相比,增加了一项ρ2(b,bgt)c2\frac{\rho ^2\left( \boldsymbol{b},\boldsymbol{b}^{\boldsymbol{gt}} \right)}{c^2},该项的计算依赖于两个参数:

1.全局框C的对角线长度c。

2.两个b-box的中心b\boldsymbol{b}bgt\boldsymbol{b}^{\boldsymbol{gt}}之间的距离d。