【pytorch】目标检测指标iou的升级版:giou实现

89 篇文章 11 订阅
65 篇文章 3 订阅
该博客介绍了GIOU(Generalized Intersection over Union)损失函数,它解决了传统IOU在目标检测中的两个问题:无重叠时无法优化和对齐方式的不敏感。GIOU是IOU的下界,取值范围在[-1,1],更适合作为距离度量。文章提供了一个PyTorch实现GIoU的代码示例,并通过具体例子展示了其计算过程,输出结果为[-0.0794]。
摘要由CSDN通过智能技术生成

相比于传统的IOU,判别重合程度时,使用GIOU,是为了解决以下两个问题:
1.预测的检测框如果和真实物体的检测框没有重叠,无法进一步优化。
2.对于两个IoU相同的物体,他们的对齐方式IoU并不敏感。
于是有如下公式:
在这里插入图片描述
GIoU对scale不敏感

GIoU是IoU的下界,在两个框无线重合的情况下,IoU=GIoU

IoU取值[0,1],但GIoU有对称区间,取值范围[-1,1]。在两者重合的时候取最大值1,在两者无交集且无限远的时候取最小值-1,因此GIoU是一个非常好的距离度量指标。

实现giou的pytorch代码为:

def box_giou( b1, b2):
    """
    输入为:
    b1: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4),
    最后一维xywh为box中心坐标及宽高
    b2: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh
    返回为:
    giou: tensor, shape=(batch, feat_w, feat_h, anchor_num, 1)
    """
    #首先计算两者IOU
    '''
    计算两框相交的部分面积InterArea:画图分析可知,a框与b框相交时,
    两框左上角中坐标值较大的一个点,及两框右下角中坐标值较小的一个点,最终围成相交区域。
    若两框及两框右下角中坐标值较小的一个点坐标减去两框左上角中坐标值较大的一个点坐标小于0,
    则证明无相交,最终结果直接赋值为0。
    '''
    #先将两者坐标转为左上角及右下角的坐标形式:
    box1=torch.zeros_like(b1)
    box2 = torch.zeros_like(b2)
    box1[...,[0,1]]=b1[...,[0,1]]-b1[...,[2,3]]/2
    box1[..., [2, 3]] = b1[..., [0, 1]] + b1[..., [2, 3]] / 2
    box2[...,[0,1]]=b2[...,[0,1]]-b2[...,[2,3]]/2
    box2[..., [2, 3]] = b2[..., [0, 1]] + b2[..., [2, 3]] / 2
    #计算两框相并的面积b1AddB2area
    leftTop=torch.max(box1[...,0:2],box2[...,0:2])
    bottomRight=torch.min(box1[...,2:4],box2[...,2:4])
    #如出现负值表示框不相交截取为0:输出[...,w,h]
    b1AndB2=torch.clamp(bottomRight-leftTop,min=0)
    #计算了相交面积,形状[...,1]
    b1AndB2Area=b1AndB2[...,0:1]*b1AndB2[...,1:2]
    #再计算b1及b2自己的面积:形状[...,1]
    b1Area=b1[...,2:3]*b1[...,3:4]
    b2Area = b2[..., 2:3] * b2[..., 3:4]
    #得出IOU的结果
    iou=b1AndB2Area/(b1Area+b2Area-b1AndB2Area)
    #然后再确定封闭b1及b2的整个矩形:确定该矩形的2个对角:
    leftTop=torch.min(box1[...,0:2],box2[...,0:2])
    bottomRight=torch.max(box1[...,2:4],box2[...,2:4])
    gap=bottomRight-leftTop
    #计算封闭矩形的面积:
    outerArea=gap[...,0:1]*gap[...,1:2]
    #返回giou
    return iou-(outerArea-(b1Area+b2Area-b1AndB2Area))/outerArea

编写程序做测试:

b1=torch.FloatTensor([1,1,2,2])
b2=torch.FloatTensor([2,2,2,2])
b1=b1.view(1,1,1,1,4)
b2=b2.view(1,1,1,1,4)
print(box_giou(b1,b2))

输出结果为

tensor([[[[[-0.0794]]]]])
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

颢师傅

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

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

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

打赏作者

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

抵扣说明:

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

余额充值