DIoU 和 CIoU 的原理与代码

AI人工智能初学者

共 4546字,需浏览 10分钟

 ·

2022-12-04 13:16

本篇接着上篇 交并比(IoU 与 GIoU 原理与实现) 继续,上篇介绍了 IoU 和 GIoU,本篇分享 DIoU 和 CIoU 的原理与实现。

DIoU 原理与实现

DIoU 原理

GIoU 虽然解决了 IoU 的一些问题,但是它并不能直接反映预测框与目标框之间的距离,DIoU(Distance-IoU)即可解决这个问题,它将两个框之间的重叠度、距离、尺度都考虑了进来。DIoU的计算公式如下:

其中, 分别代表两个框的中心点, 代表两个中心点之间的欧式距离, 代表两个图像的最小外接矩形的对角线,如图 1 所示。

图1:DIoU 原理

DIoU 相较于其他两种计算方法的优点是:

  • DIoU 可直接最小化两个框之间的距离,所以作为损失函数时 Loss 收敛更快。

  • 在两个框完全上下排列或左右排列时,没有空白区域,此时 GIoU 几乎退化为了 IoU,但是 DIoU 仍然有效。

所以,DIoU 在完善图像重叠度的计算功能的基础上,实现了对图形距离的考量,但仍无法对图形长宽比的相似性进行很好的表示。

DIoU 计算

在图 2 中,通过计算可得,中心点 、中心点 的坐标分别为:

图2:DIoU 计算

此时的 DIoU 计算公式为:

DIoU 实现

代码如下:

import numpy as np
import IoU
# box : [左上角x坐标,左上角y坐标,右下角x坐标,右下角y坐标]

box1 = [0068]
box2 = [32910]
# DIoU
def DIoU(box1, box2):
    # 计算对角线长度 C
    x1, y1, x2, y2 = box1
    x3, y3, x4, y4 = box2

     # numpy.sqrt() 函数计算给定数组中每个元素的平方根。
    C = np.sqrt((max(x2, x4) - min(x1, x3)) ** 2 +
                       (max(y2, y4) - min(y3, y1)) ** 2)

    print('C: ', C)

    # box1 中心点x坐标: x2 - (x2 - x1) / 2
    point1_x, point1_y = (x2 + x1) / 2, (y2 + y1) / 2
    # box2 中心点
    point2_x, point2_y = (x4 + x3) / 2, (y4 + y3) / 2
    # 计算中心点间距 D
    D = np.sqrt((point2_x - point1_x) ** 2 +
                       (point2_y - point1_y) ** 2)

    # 计算IoU,调用IoU(box1, box2)函数
    iou = IoU(box1, box2)
    diou = iou - (D ** 2 / C ** 2)
    return diou

print(DIoU(box1,box2))

CIoU 原理与实现

CIoU 原理

CIoU 的全称为 Complete IoU,它在 DIoU 的基础上,还同时考虑两个矩形的长宽比,也就是形状的相似性。CIoU 的计算公式为:

其中, 是权重函数,而 用来度量长宽比的相似性。计算公式为:

可以看出,CIoU 就是在 DIoU 的基础上,增加了图像相似性的影响因子,因此可以更好地反映两个框之间的差异性。

还需要注意的一点是,在使用 CIoU 作为 Loss 的时候, 的梯度同样会参与反向传播的计算,其中:

如果矩形的 均小于1, 的值则会很小,这样很容易出现梯度爆炸的现象,所以在计算 的梯度时,直接把 当做 1 来计算。论文里会在 关于 的偏导数上加负号。

至此,IoU 终于实现了对两个图像之间的重叠比例、图形距离、形状相似度(矩形长宽比)的综合度量。

CIoU 计算

继续以图 2 为例,中心点 、中心点 的坐标分别为:

此时 CIoU 的计算公式为:

由于最开始设定的两个矩形的形状相同,计算所得的形状惩罚项为 0,因此此时 CIoU=DIoU 。由此可见,两个形状差别越大,CIoU 相较于 DIoU 越小。

CIoU 实现

代码如下:

import numpy as np
import IoU
import DIoU
# box : [左上角x坐标,左上角y坐标,右下角x坐标,右下角y坐标]

box1 = [0068]
box2 = [32910]
# CIoU
def CIoU(box1, box2):
    x1, y1, x2, y2 = box1
    x3, y3, x4, y4 = box2
    # box1的宽:box1_w,box1的高:box1_h,
    box1_w = x2 - x1
    box1_h = y2 - y1
    # box2的宽:box2_w,box2的高:box2_h,
    box2_w = x4 - x3
    box2_h = y4 - y3
    iou = IoU(box1, box2)
    diou = DIoU(box1, box2)

    # v用来度量长宽比的相似性
    v = (4 / (np.pi) ** 2) * (np.arctan(int(box2_w / box2_h)) - np.arctan(int(box1_w / box1_h)))
    # α是权重函数
    a = v / ((1 + iou) + v)
    ciou = diou - a * v
    return ciou

print(CIoU(box1, box2))


今天分享了 DIoU 和 CIoU 的原理和代码,后台回复 IoU,即可获得 IoU、GIoU、DIoU 和 CIoU 的代码。

最后祝大家有所进步!

参考文献

[1] 理解梯度:https://www.cnblogs.com/zzzzy/p/8505150.html
[2] Generalized Intersection over Union:https://arxiv.org/pdf/1902.09630.pdf
[3] Distance-IoU Loss: https://arxiv.org/pdf/1911.08287.pdf
[4]
交并比(IoU 与 GIoU 原理与实现)

浏览 37
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报