IOU/GIOU/DIOU/CIOU代码

IOU/GIOU/DIOU/CIOU计算公式及代码


box示意图 在这里插入图片描述

IoU计算步骤:

  1. 计算b1和b2右下角的x坐标最小值 (注意坐标轴方向)
  2. 计算b1和b2左上角y坐标最大值
  3. w = 步骤1-步骤2 (w小于0则为0,大于0则保持不变)
  4. 计算b1和b2右下角的y坐标最小值
  5. 计算b1和b2左上角y坐标最大值 (h小于0则为0,大于0则保持不变)
  6. h = 步骤4 - 步骤5 (h小于0则为0,大于0则保持不变)
  7. IoU = w*h / (b1面积+b2面积 - w*h)
def bbox_iou(box1, box2, GIoU=False, DIoU=False, CIoU=False):
	'''
	计算box1与box2中所有box的IoU
	Returns the IoU of box1 to box2. box1 shape is (4,), box2 shapeis (n,4)
	4分别表示box的左上角xy以及右下角xy, n表示bbox的个数
	'''
	box2 = box2.t()
	# (x1,y1)为b1的左上角坐标,(x2,y2)则为其右下角坐标
    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]
    # 计算交集面积
    # (两个box右下角坐标x的最小值-两个box左上角坐标x的最大值)*
    # (两个box右下角坐标y的最小值-两个box左上角坐标y的最大值)
    # 注:这边clamp是把小于0的部分置为0,小于0就表示不相交,则计算出来的inter为0
    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
    w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1
    union = (w1 * h1 + 1e-16) + w2 * h2 - inter
    iou = inter / union  # iou

	# 计算GIoU/DIoU/CIoU
    if GIoU or DIoU or CIoU:
    	# cw和ch分别表示把b1和b2围起来最小的长方形的宽和高 convex
        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 GIoU:  # Generalized IoU https://arxiv.org/pdf/1902.09630.pdf
            c_area = cw * ch + 1e-16  # convex area
            return iou - (c_area - union) / c_area  # GIoU
        if DIoU or CIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1
            # convex对角线距离的平方
            c2 = cw ** 2 + ch ** 2 + 1e-16
            # b1和b2中心点距离的平方
            rho2 = ((b2_x1 + b2_x2) - (b1_x1 + b1_x2)) ** 2 / 4 + ((b2_y1 + b2_y2) - (b1_y1 + b1_y2)) ** 2 / 4
            if DIoU:
                return iou - rho2 / c2  # DIoU
            elif CIoU:  # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47
                v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)
                with torch.no_grad():
                    alpha = v / (1 - iou + v)
                return iou - (rho2 / c2 + v * alpha)  # CIoU

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值