IoU、GIoU、DIoU、CIoU计算方法

IoU

IoU就是我们所说的交并比,是目标检测中最常用的指标,在anchor-based的方法中,他的作用不仅用来确定正样本和负样本,还可以用来评价输出框(predict box)和ground-truth的距离。

IoU、GIoU、DIoU、CIoU计算方法
可以说它可以反映预测检测框与真实检测框的检测效果。
还有一个很好的特性就是尺度不变性,也就是对尺度不敏感(scale invariant), 在regression任务中,判断predict box和gt的距离最直接的指标就是IoU。(满足非负性;同一性;对称性;三角不等性)
IoU的一种实现方式如下:
def intersection_over_union(box1, box2, wh=False):
"""
    计算IoU(交并比)
    :param box1: bounding box1
    :param box2: bounding box2
    :param wh: 坐标的格式是否为(x,y,w,h)
    :return:计算结果
"""
    if not wh:
        xmin1, ymin1, xmax1, ymax1 = box1
        xmin2, ymin2, xmax2, ymax2 = box2
    else:
        xmin1, ymin1 = int(box1[0] - box1[2] / 2.0), int(box1[1] - box1[3] / 2.0)
        xmax1, ymax1 = int(box1[0] + box1[2] / 2.0), int(box1[1] + box1[3] / 2.0)
        xmin2, ymin2 = int(box2[0] - box2[2] / 2.0), int(box2[1] - box2[3] / 2.0)
        xmax2, ymax2 = int(box2[0] + box2[2] / 2.0), int(box2[1] + box2[3] / 2.0)
    # 获取矩形框交集对应的左上角和右下角的坐标(intersection)
    xx1 = max([xmin1, xmin2])
    yy1 = max([ymin1, ymin2])
    xx2 = min([xmax1, xmax2])
    yy2 = min([ymax1, ymax2])
    # 计算两个矩形框面积
    area1 = (xmax1 - xmin1) * (ymax1 - ymin1)
    area2 = (xmax2 - xmin2) * (ymax2 - ymin2)
    inter_area = (max([0, xx2 - xx1])) * (max([0, yy2 - yy1]))  # 计算交集面积
    iou = inter_area / (area1 + area2 - inter_area + 1e-6)  # 计算交并比
    return iou

GIoU

在CVPR2019中,论文《Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression》
提出了GIoU的思想。由于IoU是比值的概念,对目标物体的scale是不敏感的。然而检测任务中的BBox的回归损失(MSE loss, l1-smooth loss等)优化和IoU优化不是完全等价的,而且 Ln 范数对物体的scale也比较敏感,IoU无法直接优化没有重叠的部分。

这篇论文提出可以直接把IoU设为回归的loss。

IoU、GIoU、DIoU、CIoU计算方法
上面公式的意思是:先计算两个框的最小闭包区域面积A c A_c A c ​(通俗理解:同时包含了预测框和真实框的最小框的面积),再计算出IoU,再计算闭包区域中不属于两个框的区域占闭包区域的比重,最后用IoU减去这个比重得到GIoU。
GIoU的一种实现方式如下:
def g_iou(rec1, rec2):
"""
    计算GIoU
    :param rec1: bounding box1(xmin, ymin, xmax, ymax)格式
    :param rec2: bounding box2(xmin, ymin, xmax, ymax)格式
    :return: 计算结果
"""
    # xmin, ymin, xmax, ymax格式
    xmin1, ymin1, xmax1, ymax1 = rec1
    xmin2, ymin2, xmax2, ymax2 = rec2
    iou = intersection_over_union(rec1, rec2)
    area_closure = (max(xmin1, xmax1, xmin2, xmax2) - min(xmin1, xmax1, xmin2, xmax2)) * (
            max(ymin1, ymax1, ymin2, ymax2) - min(ymin1, ymax1, ymin2, ymax2))
    area_1 = (xmax1 - xmin1) * (ymax1 - ymin1)
    area_2 = (xmax2 - xmin2) * (ymax2 - ymin2)
    sum_area = area_1 + area_2

    w1 = xmax1 - xmin1  # 第一个矩形的宽
    w2 = xmax2 - xmin2  # 第二个矩形的宽
    h1 = ymax1 - ymin1
    h2 = ymax2 - ymin2
    w = min(xmin1, xmax1, xmin2, xmax2) + w1 + w2 - max(xmin1, xmax1, xmin2, xmax2)  # 交叉部分的宽
    h = min(ymin1, ymax1, ymin2, ymax2) + h1 + h2 - max(ymin1, ymax1, ymin2, ymax2)  # 交叉部分的高
    intersection_area = w * h  # 交叉的面积
    add_area = sum_area - intersection_area  # 两矩形并集的面积
    end_area = (area_closure - add_area) / area_closure  # 闭包区域中不属于两个框的区域占闭包区域的比重
    giou = iou - end_area
    return giou

DIoU

DIoU要比GIou更加符合目标框回归的机制,将目标与anchor之间的距离,重叠率以及尺度都考虑进去,使得目标框回归变得更加稳定,不会像IoU和GIoU一样出现训练过程中发散等问题。

IoU、GIoU、DIoU、CIoU计算方法
其中,b b b ,b g t b^{gt}b g t 分别代表了预测框和真实框的中心点,且 ρ \rho ρ代表的是计算两个中心点间的欧式距离。 c c c 代表的是能够同时包含预测框和真实框的最小闭包区域的对角线距离。
一种DIoU的实现方式:

def d_iou(rec1, rec2):
"""
    计算DIoU
    :param rec1: bounding box1(xmin, ymin, xmax, ymax)格式
    :param rec2: bounding box2(xmin, ymin, xmax, ymax)格式
    :return: 计算结果
"""
    # xmin, ymin, xmax, ymax格式
    xmin1, ymin1, xmax1, ymax1 = rec1
    xmin2, ymin2, xmax2, ymax2 = rec2
    iou = intersection_over_union(rec1, rec2)
    # 中心点距离平方
    center1 = ((xmin1 + xmax1) / 2, (ymin1 + ymax1) / 2)
    center2 = ((xmin2 + xmax2) / 2, (ymin2 + ymax2) / 2)
    d_center2 = (center1[0] - center2[0]) ** 2 + (center1[1] - center2[1]) ** 2
    # 最小闭包矩形对角线长度平方
    corner1 = (min(xmin1, xmax1, xmin2, xmax2), min(ymin1, ymax1, ymin2, ymax2))
    corner2 = (max(xmin1, xmax1, xmin2, xmax2), max(ymin1, ymax1, ymin2, ymax2))
    d_corner2 = (corner1[0] - corner2[0]) ** 2 + (corner1[1] + corner2[1]) ** 2
    diou = iou - d_center2 / d_corner2
    return diou

CIoU

考虑到bbox回归三要素中的长宽比还没被考虑到计算中,因此,进一步在DIoU的基础上提出了CIoU。其惩罚项如下面公式:

IoU、GIoU、DIoU、CIoU计算方法
其中α \alpha α是权重函数
而v v v用来度量长宽比的相似性,定义为:
IoU、GIoU、DIoU、CIoU计算方法
完整的 CIoU 损失函数定义:
IoU、GIoU、DIoU、CIoU计算方法
一种CIoU的实现方式如下:
import numpy

def c_iou(rec1, rec2):
"""
    计算CIoU
    :param rec1: bounding box1(xmin, ymin, xmax, ymax)格式
    :param rec2: bounding box2(xmin, ymin, xmax, ymax)格式
    :return: 计算结果
"""
    # xmin, ymin, xmax, ymax格式
    xmin1, ymin1, xmax1, ymax1 = rec1
    xmin2, ymin2, xmax2, ymax2 = rec2
    iou = intersection_over_union(rec1, rec2)
    # 中心点距离平方
    center1 = ((xmin1 + xmax1) / 2, (ymin1 + ymax1) / 2)
    center2 = ((xmin2 + xmax2) / 2, (ymin2 + ymax2) / 2)
    d_center2 = (center1[0] - center2[0]) ** 2 + (center1[1] - center2[1]) ** 2
    # 最小闭包矩形对角线长度平方
    corner1 = (min(xmin1, xmax1, xmin2, xmax2), min(ymin1, ymax1, ymin2, ymax2))
    corner2 = (max(xmin1, xmax1, xmin2, xmax2), max(ymin1, ymax1, ymin2, ymax2))
    d_corner2 = (corner1[0] - corner2[0]) ** 2 + (corner1[1] + corner2[1]) ** 2
    w1, h1 = xmax1 - xmin1, ymax1 - ymin1
    w2, h2 = xmax2 - xmin2, ymax2 - ymin2
    # 度量长宽比的参数
    v = 4 * (np.arctan(w1 / h1) - np.arctan(w2 / h2)) ** 2 / (np.pi ** 2)
    alpha = v / (1 - iou + v)
    ciou = iou - d_center2 / d_corner2 - alpha * v
    return ciou

Original: https://blog.csdn.net/Ray_awakepure/article/details/121594033
Author: Ray_awakepure
Title: IoU、GIoU、DIoU、CIoU计算方法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/683166/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球