【目标检测】IoU、GIoU、DIoU、CIoU、EIoU 5大评价指标

news2025/2/23 10:08:16

目录

一、简介

二、IoU(Intersection over Union)

三、GIoU(Generalized IoU)

四、DIoU(Distance-IoU)

五、CIoU(Complete-IoU)

六、EIoU(Efficient-IoU)

七、pytorch代码实现

七、总结


一、简介

        在目标检测任务中,常用到一个指标IoU,即交并比,IoU可以很好的描述一个目标检测模型的好坏。在训练阶段IoU可以作为anchor-based方法中,划分正负样本的依据;同时也可用作损失函数;在推理阶段,NMS中会用到IoU。同时IoU有着比较严重的缺陷,于是出现了GIoU、DIoU、CIoU、EIoU,下面我们一起看一下这几种IoU。

二、IoU(Intersection over Union)

        IoU的计算是用预测框(A)和真实框(B)的交集除以二者的并集,其公式为:

IoU=\frac{A\cap B}{A\cup B}

        IoU的值越高也说明A框与B框重合程度越高,代表模型预测越准确。反之,IoU越低模型性能越差。

IoU优点:

        (1)IoU具有尺度不变性

        (2)结果非负,且范围是(0, 1)

IoU缺点:

        (1)如果两个目标没有重叠,IoU将会为0,并且不会反应两个目标之间的距离,在这种无重叠目标的情况下,如果IoU用作于损失函数,梯度为0,无法优化。

        (2)IoU无法精确的反映两者的重合度大小。如下图所示,三种情况IoU都相等,但看得出来他们的重合度是不一样的,左边的图回归的效果最好,右边的最差。

三、GIoU(Generalized IoU)

        论文地址:https://arxiv.org/pdf/1902.09630.pdf

        为了解决IoU作为损失函数时的两个缺点,有大神提出了GIoU,在IoU后面增加了一项,计算两个框的最小外接矩形,用于表征两个框的距离,从而解决了两个目标没有交集时梯度为零的问题,公式为:

GIoU=IoU-\frac{C-(A\cup B)}{C}

        其中C是两个框的最小外接矩形的面积。

        当IOU=0时:

GIoU=-1+\frac{A\cup B}{C}

        当IOU为0时,意味着A与B没有交集,这个时候两个框离得越远,GIOU越接近-1;两框重合,GIOU=1,所以GIOU的取值为(-1, 1]。

         GIOU作为loss函数时:

L_{GIoU}=1-GIoU

        当A、B两框不相交时A\cup B不变,最大化GIoU就是最小化C,这样就会促使两个框不断靠近。

优点:

        (1)当IoU=0时,仍然可以很好的表示两个框的距离。

        (2)GIoU不仅关注重叠区域,还关注其他的非重合区域,能更好的反映两者的重合度。

缺点:

        (1)当两个框属于包含关系时,GIoU会退化成IoU,无法区分其相对位置关系,如下图:

         (2)由于GIoU仍然严重依赖IoU,因此在两个垂直方向,误差很大,很难收敛。两个框在相同距离的情况下,水平垂直方向时,此部分面积最小,对loss的贡献也就越小,从而导致在垂直水平方向上回归效果较差。

        如下图,三种情况下GIoU的值一样,GIoU将很难区分这种情况。

四、DIoU(Distance-IoU)

        论文地址:https://arxiv.org/pdf/1911.08287.pdf

        针对上述GIoU的两个问题,有大神将GIoU中最小外接框来最大化重叠面积的惩罚项修改成最小化两个BBox中心点的标准化距离从而加速损失的收敛过程,这就诞生了DIoU。

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

        公式如下:

DIoU=IoU-\frac{\rho ^2(b,b^{gt})}{c^2}

        其中b,b^{gt}分别代表了预测框和真实框的中心点,且 ρ 代表的是计算两个中心点间的欧式距离。 c 代表的是能够同时包含预测框和真实框的最小外接矩形的对角线长度。

优点:

        (1)DIoU loss可以直接最小化两个目标框的距离,因此比GIoU loss收敛快得多。

        (2)对于包含两个框在水平方向和垂直方向上这种情况,DIoU损失可以使回归非常快。

        (3)DIoU还可以替换普通的IoU评价策略,应用于NMS中,使得NMS得到的结果更加合理和有效。

缺点:

        虽然DIOU能够直接最小化预测框和真实框的中心点距离加速收敛,但是Bounding box的回归还有一个重要的因素纵横比暂未考虑。如下图,三个红框的面积相同,但是长宽比不一样,红框与绿框中心点重合,这时三种情况的DIoU相同,证明DIoU不能很好的区分这种情况。

五、CIoU(Complete-IoU)

        CIoU与DIoU出自同一篇论文,CIoU大多数用于训练。DIoU的作者考虑到,在两个框中心点重合时,c与d的值都不变。所以此时需要引入框的宽高比:

CIoU=IoU-(\frac{\rho ^2(b,b^{gt})}{c^2}+\alpha v)

        其中α是权重函数,v用来度量宽高比的一致性:

\alpha =\frac{v}{(1-IoU)+v}

v=\frac{4}{\pi ^2}(arctan\frac{w_{gt}}{h_{gt}}-arctan(\frac{w}{h}))^2

        最终CIoU Loss定义为:

L_{CIoU}=1-IoU+\frac{\rho ^2(b,b^{gt})}{c^2}+av

优点:

        考虑了框的纵横比,可以解决DIoU的问题。

缺点:

        通过CIoU公式中的v反映的纵横比的差异,而不是宽高分别与其置信度的真实差异,所以有时会阻碍模型有效的优化相似性。

六、EIoU(Efficient-IoU)

        论文地址:https://arxiv.org/pdf/2101.08158.pdf

        为了解决CIoU的问题,有学者在CIOU的基础上将纵横比拆开,提出了EIOU Loss,并且加入Focal聚焦优质的预测框,与CIoU相似的,EIoU是损失函数的解决方案,只用于训练。

        EIOU的惩罚项是在CIOU的惩罚项基础上将纵横比的影响因子拆开分别计算目标框和预测框的长和宽,该损失函数包含三个部分:重叠损失,中心距离损失,宽高损失,前两部分延续CIoU中的方法,但是宽高损失直接使目标框与预测框的宽度和高度之差最小,使得收敛速度更快。惩罚项公式如下:

L_{EIoU}=L_{IoU}+L_{dic}+L_{asp}

=1-Iou+\frac{\rho ^2(b,b^{gt})}{(c_w)^2+(c_h)^2}+\frac{\rho ^2(w,w^{gt})}{(c_w)^2}+\frac{\rho ^2(h,h^{gt})}{(c_h)^2}

        其中 c_wc_h 是覆盖两个Box的最小外接框的宽度和高度。

        通过整合EIoU Loss和FocalL1 loss,最终得到了最终的Focal-EIoU loss,其中 γ是一个用于控制曲线弧度的超参。

L_{Focal-EIou}=IoU^\gamma L_{EIoU}

优点:

1)将纵横比的损失项拆分成预测的宽高分别与最小外接框宽高的差值,加速了收敛提高了回归精度。

2)引入了Focal Loss优化了边界框回归任务中的样本不平衡问题,即减少与目标框重叠较少的大量锚框对BBox 回归的优化贡献,使回归过程专注于高质量锚框。

七、pytorch代码实现

        代码中使用pytorch是方便在作为损失函数的时候,方便反向传播,下面的代码计算各种IoU,用作损失函数的时候需要用1减去返回结果。

import torch
import math
import numpy as np


def bbox_iou(box1, box2, xywh=False, giou=False, diou=False, ciou=False, eiou=False, eps=1e-7):
    """
    实现各种IoU
    Parameters
    ----------
    box1        shape(b, c, h, w,4)
    box2        shape(b, c, h, w,4)
    xywh        是否使用中心点和wh,如果是False,输入就是左上右下四个坐标
    GIoU        是否GIoU
    DIoU        是否DIoU
    CIoU        是否CIoU
    EIoU        是否EIoU
    eps         防止除零的小量

    Returns
    -------

    """
    # 获取边界框的坐标
    if xywh:
        # 将 xywh 转换成 xyxy
        b1_x1, b1_x2 = box1[..., 0] - box1[..., 2] / 2, box1[..., 0] + box1[..., 2] / 2
        b1_y1, b1_y2 = box1[..., 1] - box1[..., 3] / 2, box1[..., 1] + box1[..., 3] / 2
        b2_x1, b2_x2 = box2[..., 0] - box2[..., 2] / 2, box2[..., 0] + box2[..., 2] / 2
        b2_y1, b2_y2 = box2[..., 1] - box2[..., 3] / 2, box2[..., 1] + box2[..., 3] / 2

    else:
        # x1, y1, x2, y2 = box1
        b1_x1, b1_y1, b1_x2, b1_y2 = box1[..., 0], box1[..., 1], box1[..., 2], box1[..., 3]
        b2_x1, b2_y1, b2_x2, b2_y2 = box2[..., 0], box2[..., 1], box2[..., 2], box2[..., 3]

    # 区域交集
    inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \
            (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)

    # 区域并集
    w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps
    w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps
    union = w1 * h1 + w2 * h2 - inter + eps
    # 计算iou
    iou = inter / union

    if giou or diou or ciou or eiou:
        # 计算最小外接矩形的wh
        cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)
        ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)

        if ciou or diou or eiou:
            # 计算最小外接矩形角线的平方
            c2 = cw ** 2 + ch ** 2 + eps
            # 计算最小外接矩形中点距离的平方
            rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 +
                    (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4
            if diou:
                # 输出DIoU
                return iou - rho2 / c2
            elif ciou:
                v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)
                with torch.no_grad():
                    alpha = v / (v - iou + (1 + eps))
                # 输出CIoU
                return iou - (rho2 / c2 + v * alpha)
            elif eiou:
                rho_w2 = ((b2_x2 - b2_x1) - (b1_x2 - b1_x1)) ** 2
                rho_h2 = ((b2_y2 - b2_y1) - (b1_y2 - b1_y1)) ** 2
                cw2 = cw ** 2 + eps
                ch2 = ch ** 2 + eps
                # 输出EIoU
                return iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2)
        else:
            c_area = cw * ch + eps  # convex area
            # 输出GIoU
            return iou - (c_area - union) / c_area
    else:
        # 输出IoU
        return iou


if __name__ == '__main__':
    box1 = torch.from_numpy(np.asarray([170, 110, 310, 370]))
    box1 = box1.expand(1, 1, 1, 1, 4)
    # 有交集
    box2 = torch.from_numpy(np.asarray([250, 60, 375, 300]))
    box2 = box2.expand(1, 1, 1, 1, 4)
    # 无交集
    box3 = torch.from_numpy(np.asarray([730, 420, 1000, 700]))
    box3 = box3.expand(1, 1, 1, 1, 4)
    print('iou有交集:', bbox_iou(box1, box2))
    print('giou有交集:', bbox_iou(box1, box2, giou=True))
    print('diou有交集:', bbox_iou(box1, box2, diou=True))
    print('ciou有交集:', bbox_iou(box1, box2, ciou=True))
    print('eiou有交集:', bbox_iou(box1, box2, eiou=True))
    print("=" * 20)
    print('iou无交集:', bbox_iou(box1, box3))
    print('giou无交集:', bbox_iou(box1, box3, giou=True))
    print('diou无交集:', bbox_iou(box1, box3, diou=True))
    print('ciou无交集:', bbox_iou(box1, box3, ciou=True))
    print('eiou无交集:', bbox_iou(box1, box3, eiou=True))

七、总结

        边界框回归的三大几何因素:重叠面积、中心点距离、纵横比。

重叠中心点纵横比优点缺点
IoU

××尺度不变性,非负性;同一性;对称性;三角不等性。1.如果两个框不相交,不能反映两个框距离远近 2.无法精确的反映两个框的重合度大小
GIoU××解决检测框和真实框没有重叠时loss等于0问题

1.当检测框和真实框出现包含现象的时候GIOU退化成IOU

2.两个框相交时,在水平和垂直方向上收敛慢

DIoU×直接回归两个框中心点的欧式距离,加速收敛。回归过程中未考虑Bounding box的纵横比,精确度上尚有进一步提升的空间
CIoU增加了检测框尺度的loss,增加了长和宽的loss,这样预测框就会更加的符合真实框。

1. 纵横比描述的是相对值,存在一定的模糊

2. 未考虑难易样本的平衡问题

EIoU分别计算宽高的差异值取代了纵横比,同时引入Focal Loss解决难易样本不平衡的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/71448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

即时通讯开发之如何测试实时语音通话质量

实时语音聊天开发,对于一般的开发者来说比较神秘,很多朋友不太清楚如何全面的评估一个音频引擎。很多朋友还停留在这样的初级阶段:把demo调通,找几个人喂喂喂......凭自己优异的听觉感受一下,整个测试过程就完成了。 但…

【嵌入式硬件芯片开发笔记】EEPROM芯片M24C32配置流程

【嵌入式硬件芯片开发笔记】EEPROM芯片M24C32配置流程 32-Kbit serial IC bus EEPROM - 105C operation 适用于M24C32/M24C32-DRE 读取存储的从机地址为:0x50 读取标识页面的从机地址为:0x58 WC引脚接地,存储可以进行写操作 地址长度为16位 存…

117. 填充每个节点的下一个右侧节点指针 II

文章目录1. 背2. 题目3. 答案1. 背 这道题本来可以很简答,一个队列,存储指针和它的行数就OK了,但是这道题的难点在于不用额外空间复杂度。 横向看一下,这一行是不是就是一个链表呢? 多加一个变量,用来存储第…

C++入门教程||C++ 判断||C++ 日期 时间

判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。 下面是大多数编程语言中典型的判断结构的一般形式: 判断语句 C 编程语言提…

three.js实战 -自定义剪切器

1. 前言 这是我在github上看到大佬的一个作品,当时感觉很有意思,决定分享出来,不知道取这个名字是否正确,废话不多说看下面效果。 2.demo效果 3.需要掌握的知识 矩阵的基本运算,能够认是到一些基本变换用到的矩阵(…

晶圆级倒装装备及控制系统

晶圆级倒装装备主要由晶圆盘进料模块、晶圆盘工作台模块、覆晶模块、焊头模块、基板工作台模块、点胶模块、视觉模块和基板进出料模块组成,如图 2-2 所示。 晶圆级倒装装备控制系统结构晶圆级倒装装备的运控系统主要由工控机、运动控制卡、驱动器、反馈装置和直线电…

QA:observable and Subject

概念区别和常见的错误理解辩证: 通俗理解一下 1. Observable 是一条 "水管蓝图" ,每次打开水龙头,水流会按照设计好的路线流向终点。起点和终点一一对应。每次打开水流,都是新的流,水流之间互不影响。一次一管。 2. …

VMWare虚拟机设置CentOS7共享文件夹

1. 目录 系统版本:CentOS 7.9 文章目录1. 目录2. VMWare:虚拟机设置,设置共享文件夹3. 虚拟机设置:手动挂载共享文件夹4. 检查是否挂载成功5. (可选)创建共享文件夹的软链接(快捷方式)6. (可选)定时任务开机自动挂载2. VMWare&am…

博客文章分类导引(持续更新)

摘要:本文提供一篇博客目录,有物联网、安卓编程、硬件设计等若干主题,这些主题一般都是成系统的,可以实现从零开始做出自己的物联网系统。 文章结构如下: 1.物联网专栏 使用arduino编写mqtt客户端连接emqx服务器 VSC…

vue.js:组件化的实现和使用过程

什么是组件化? 当我们遇到复杂问题的时候: 任何一个人处理信息的逻辑能力都是有限的所以,当我们面对一个复杂的问题的时候,我们不可能一次性搞定处理掉一大堆内容但是我们都会有问题拆解的能力将一个复杂的问题拆解成很多小的问…

Springcloud笔记之Ribbon

Ribbon:负载均衡(基于客户端)1. 负载均衡以及Ribbon1.1 Ribbon 的概念1.2 Ribbon 的作用2. 集成Ribbon3. 使用Ribbon实现负载均衡3.1 步骤3.2 自定义规则1. 负载均衡以及Ribbon 1.1 Ribbon 的概念 Spring Cloud Ribbon 是基于Netflix Ribbo…

[附源码]计算机毕业设计JAVA智能超市导购系统

[附源码]计算机毕业设计JAVA智能超市导购系统 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybati…

WebRTC Native M96 回调音频裸数据IAudioFrameObserver--采集的音频(onRecordAudioFrame)

上篇已经说道,通过注册回调,给上层APP抛音频裸数据: 《WebRTC Native M96 SDK接口封装–注册语音观测器对象获取原始音频数据registerAudioFrameObserver》[https://dabaojian.blog.csdn.net/article/details/128218542] 此篇,就详细讲述一下,如果实现onRecordAudioFrame…

vue学习笔记(二)-vue生命周期

概念 a.又名生命周期回调函数、生命周期函数、生命周期钩子b.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数c.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的d.生命周期函数中的 this 指向是vm或组件实例对象 示例代码&am…

来一场关于元宇宙可持续的灵魂辩论|BOOK DAO 内容共建 第6期 招募

小杜《元宇宙创意图谱》是 BOOK DAO 的共建书籍项目,12.03我们举行了虚拟时尚主题的第5次公开共建活动。本周六晚8点,我们将举办第6期 元宇宙可持续 专题的共建活动。BOOK DAO 以搭建产业界与用户之间的交流平台、挖掘业界最值得深入探讨研究的话题为目标…

【linux】ssh免密登录

概要 服务器免密登录实际上是基于公钥的认证,比如希望A服务器可以免密访问B服务器,则需要进行如下步骤 A服务器生成密钥对将A服务器生成的公钥分发到B服务器(写入~/.ssh/authorized_keys)A服务器即可免密登录B服务器 生成密钥对…

特殊类的设计(单类模式)

一.不能拷贝的类 首先要知道拷贝的场景:拷贝构造函数以及赋值运算符重载,想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 方法1:将这两个函数只声明,不定义(防止编译器默…

【愚公系列】2022年12月 Redis数据库-Cache和Redis缓存的无缝切换使用

文章目录前言一、Cache和Redis缓存的无缝切换使用1.安装包2.服务配置3.创建控制器4.启动程序前言 Redis是分布式缓存,是将数据随机分配到不同服务器的,catch属于单机缓存,只能本机访问。 Redis和Cache的区别吧 Redis和cache都是将数据存放…

Nginx rewrite 详解

Nginx rewrite 详解 本篇主要介绍 nginx 的 rewrite 重定向这个功能进行 详解介绍, 以及介绍它的使用场景 1. rewrite 基本介绍 rewrite是实现URL重写的关键指令,根据regex (正则表达式)部分内容,重定向到replacement,结尾是flag标记。 基本语法: re…

JAVA SCRIPT设计模式--结构型--设计模式之Decorator装饰模式(9)

JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代…