目标检测 - IoU和GIoU作为边框回归的损失和代码实现

本文介绍了IoU(Intersection over Union)和GIoU(Generalized Intersection over Union)在目标检测任务中作为边框回归损失的原理,包括计算方法和代码实现。GIoU通过最小封闭框的概念改进了IoU,提供了更精确的评估。作者还提供了不同类型的IoU Loss代码示例,如UnitBox的IoU和GIoU版本。
摘要由CSDN通过智能技术生成

目标检测 - IoU和GIoU作为边框回归的损失和代码实现

flyfish

GIoU
=General-IOU
=Generalized Intersection over Union

论文《Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression》

IoU和GIoU作为边框回归的损失

GIoU as Loss for Bounding Box Regression
算法过程如下

输入: 预测的边框 B p B^p Bp 和 GT边框 B g B^g Bg坐标
B p = ( x 1 p , y 1 p , x 2 p , y 2 p ) B^p = (x^p_1,y^p_1,x^p_2,y^p_2) Bp=(x1p,y1p,x2p,y2p), B g = ( x 1 g , y 1 g , x 2 g , y 2 g ) B^g = (x^g_1,y^g_1,x^g_2,y^g_2) Bg=(x1g,y1g,x2g,y2g)
输出: L I o U \mathcal{L}_{IoU} LIoU, L G I o U \mathcal{L}_{GIoU} LGIoU

  1. 对于预测的边框 B p B^p Bp, 确保 x 2 p > x 1 p x^p_2>x^p_1 x2p>x1p y 2 p > y 1 p y^p_2>y^p_1 y2p>y1p:
    x ^ 1 p = min ⁡ ( x 1 p , x 2 p ) \hat{x}^p_1 = \min(x^p_1,x^p_2) x^1p=min(x1p,x2p),
    x ^ 2 p = max ⁡ ( x 1 p , x 2 p ) \hat{x}^p_2 = \max(x^p_1,x^p_2) x^2p=max(x1p,x2p),
    y ^ 1 p = min ⁡ ( y 1 p , y 2 p ) \hat{y}^p_1 = \min(y^p_1,y^p_2) y^1p=min(y1p,y2p),
    y ^ 2 p = max ⁡ ( y 1 p , y 2 p ) \hat{y}^p_2 = \max(y^p_1,y^p_2) y^2p=max(y1p,y2p)
  2. 计算 B g B^g Bg的面积: A g = ( x 2 g − x 1 g ) × ( y 2 g − y 1 g ) A^g = (x^g_2 - x^g_1)\times(y^g_2 - y^g_1) Ag=(x2gx1g)×(y2gy1g)
  3. 计算 B p B^p Bp的面积: A p = ( x ^ 2 p − x ^ 1 p ) × ( y ^ 2 p − y ^ 1 p ) A^p = (\hat{x}^p_2 - \hat{x}^p_1)\times(\hat{y}^p_2 - \hat{y}^p_1) Ap=(x^2px^1p)×(y^2py^1p)
  4. B p B^p Bp B g B^g Bg之间计算交集 I \mathcal{I} I :
    x 1 I = max ⁡ ( x ^ 1 p , x 1 g ) x^{\mathcal{I}}_1 = \max(\hat{x}^p_1,x^g_1) x1I=max(x^1p,x1g),
    x 2 I = min ⁡ ( x ^ 2 p , x 2 g ) x^{\mathcal{I}}_2 = \min(\hat{x}^p_2,x^g_2) x2I=min(x^2p,x2g),
    y 1 I = max ⁡ ( y ^ 1 p , y 1 g ) y^{\mathcal{I}}_1 = \max(\hat{y}^p_1,y^g_1) y1I=max(y^1p,y1g),
    y 2 I = min ⁡ ( y ^ 2 p , y 2 g ) y^{\mathcal{I}}_2 = \min(\hat{y}^p_2,y^g_2) y2I=min(y^2p,y2g),
    I = { ( x 2 I − x 1 I ) × ( y 2 I − y 1 I ) if x 2 I > x 1 I , y 2 I > y 1 I , 0 otherwise \mathcal{I} = \begin{cases} (x^{\mathcal{I}}_2 - x^{\mathcal{I}}_1) \times (y^{\mathcal{I}}_2 - y^{\mathcal{I}}_1) & \text{if} \quad x^{\mathcal{I}}_2 > x^{\mathcal{I}}_1, y^{\mathcal{I}}_2 > y^{\mathcal{I}}_1, \\ 0 & \text{otherwise} \end{cases} I={(x2Ix1I)×(y2Iy1I)0ifx2I>x1I,y2I>y1I,otherwise
  5. 寻找最小封闭框(smallest enclosing box,可看下图更清楚)的坐标 B c B^c Bc:
    x 1 c = min ⁡ ( x ^ 1 p , x 1 g ) x^{c}_1 = \min(\hat{x}^p_1,x^g_1) x1c=min(x^1p,x1g),
    x 2 c = max ⁡ ( x ^ 2 p , x 2 g ) x^{c}_2 = \max(\hat{x}^p_2,x^g_2) x2c=max(x^2p,x2g),
    y 1 c = min ⁡ ( y ^ 1 p , y 1 g ) y^{c}_1 = \min(\hat{y}^p_1,y^g_1) y1c=min(y^1p,y1g),
    y 2 c = max ⁡ ( y ^ 2 p , y 2 g ) y^{c}_2 = \max(\hat{y}^p_2,y^g_2) y2c=max(y^2p,y2g)
  6. 计算 B c B^c Bc的面积: A c = ( x 2 c − x 1 c ) × ( y 2 c − y 1 c ) A^c = (x^c_2 - x^c_1)\times(y^c_2 - y^c_1) Ac=(x2cx1c)×(y2cy1c)
  7. I o U = I U \displaystyle IoU = \frac{\mathcal{I}}{\mathcal{U}} IoU=UI, where U = A p + A g − I \mathcal{U} = A^p+A^g-\mathcal{I} U=Ap+AgI
  8. G I o U = I o U − A c − U A c \displaystyle GIoU = IoU - \frac{A^c-\mathcal{U}}{A^c} GIoU=IoUAcAcU
  9. L I o U = 1 − I o U \mathcal{L}_{IoU} = 1 - IoU LIoU=1IoU, L G I o U = 1 − G I o U \mathcal{L}_{GIoU} = 1 - GIoU LGIoU=1GIoU

用图说明的更清楚
IoU=Jaccard Index
IoU
最小的封闭框是如何计算的
在这里插入图片描述

B p B^p Bp B g B^g Bg之间计算黄色的交集 I \mathcal{I} I,绿色边框表示最小的封闭框 B c B^c Bc
最小封闭框=C
在这里插入图片描述

代码实现

关于IoU Loss

根据论文UnitBox和论文GIoU对与IoU Loss处理不同的方法
UnitBox的是-ln(IoU) ln是以e为底的对数
在这里插入图片描述
图上的坐标tblr的表示方式是这里的第三种Center-Size coordinates
y i = log ⁡ e ( x i ) y_{i} = \log_{e} (x_{i}) yi=loge(xi)
输出是 x i x_{i} xi 输出是 y i y_{i} yi

GIoU里的是1-IoU
所以代码实现的时候,可以同时实现三个Loss
参考
UnitBox: An Advanced Object Detection Network

代码中的坐标表示方法采用了这里中的第一种boundary coordinates (x_min, y_min, x_max, y_max)
0,1,2,3下标可表示left,top,right,bottom
x2>x1,y2>y1

import torch
import torch.nn as nn
class IoULoss(nn.Module):
    """
    Intersetion Over Union (IoU) loss 支持三种不同的loss计算方法:
    * IoU(UnitBox paper)
    * Linear IoU(GIoU paper)
    * gIoU
    * 类型支持:iou,linear_iou,giou
    """
    def __init__(self, loc_loss_type='giou'):
        super(IoULoss, self).__init__()
        self.loc_loss_type = loc_loss_type

    def forward(self, pred, gt, weight=None):
        """
        Args:
            pred: Nx4 predicted bounding boxes, Each row is (x1, y1, x2, y2).
            gt: Nx4 gt bounding boxes
        """
        pred_x1 = pred[:, 0]
        print(pred_x1)
        pred_y1 = pred[:, 1]
        pred_x2 = pred[:, 2]
        pred_y2 = pred[:, 3]

        gt_x1 = gt[:, 0]
        gt_y1 = gt[:, 1]
        gt_x2 = gt[:, 2]
        gt_y2 = gt[:, 3]
        #如果再严谨些,代码确保x2>x1,y2>y1,下标0和下标2,谁小谁是x1

        gt_aera = (gt_x1 + gt_x2) * (gt_y1 + gt_y2) #对应算法第2步
        pred_aera = (pred_x1 + pred_x2) * (pred_y1 + pred_y2)#对应算法第3步

        I_x1 = torch.max(pred_x1, gt_x1)
        I_x2 = torch.min(pred_x2, gt_x2)
        I_y1 = torch.max(pred_y1, gt_y1)
        I_y2 = torch.min(pred_x2, gt_x2)
        area_intersect=(I_x2 - I_x1)*(I_y2-I_y1)#交集 对应算法第4步

        C_x1 = torch.min(pred_x1, gt_x1)
        C_x2 = torch.max(pred_x2, gt_x2)
        C_y1 = torch.min(pred_y1, gt_y1)
        C_y2 = torch.max(pred_x2, gt_x2)
        ac =(C_x2 - C_x1) * (C_y2 - C_y1)#最小封闭框 #对应算法第5步

        U = gt_aera + pred_aera - area_intersect#并集

        ious = (area_intersect ) / (U.clamp(min=1e-10))#分母不为0
        gious = ious - (ac - U) / ac.clamp(min=1e-10)
        if self.loc_loss_type == 'iou':
            losses = -torch.log(ious)
        elif self.loc_loss_type == 'linear_iou':
            losses = 1 - ious
        elif self.loc_loss_type == 'giou':
            losses = 1 - gious
        else:
            raise NotImplementedError

        if weight is not None:
            return (losses * weight).sum()
        else:
            return losses.sum()

GIoU官方实现代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西笑生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值