IoU、GIoU、CIoU、DIoU(附加代码)

IoU、GIoU、CIoU、DIoU(附加代码)

IoU

  IoU的值表示预测框A和真实框B之间交并比的差值,反映预测检测框的检测效果。

在这里插入图片描述

  公式:
I o U = ( A ∩ B A ∪ B ) IoU= (\frac {A ∩ B}{A ∪ B} ) \quad IoU=(ABAB)
  IoU_loss其实就是 I o U l o s s = 1 − I o U IoU_{loss} = 1 - IoU IoUloss=1IoU
  两个矩形直接的交并比越大,那么对应的IoU_loss就会越小。
在这里插入图片描述

GIoU

  IoU有两个个弊端,第一个就跟下面这张图一样,预测框和真实框之间的IoU都为0,但是上面的预测的预测框明显要比下面的好一点,那这样IoU_loss就没有了对比性。在这里插入图片描述
  第二个弊端就是下面的图片,它们的IoU其实都是一样的,但是两个矩形框的重合的明显有差别,那IoU_loss此时也失去了对比性。
在这里插入图片描述
  所以GIoU就来了。
在这里插入图片描述
  GIoU就是在原来的IOU损失的基础上加上一个惩罚项。
  蓝色是真实目标边界框A,红色是预测目标边界框B,最外面的黄色边框C是将红绿矩形用最小矩形框起来的边界。加入非重合区域的影响,当IOU值相同时,非重合区域占比越小,代表预测框与目标框的对比效果越好。当A和B完全重合时,GIOU = 1。当A和B交集为空时,且A和B离的无限远时,即GIOU = -1。

G I o U = ( I o U − ∣ C − A ∪ B ∣ C ) GIoU= (IoU - \frac {|C - A ∪ B|}{C} ) \quad GIoU=(IoUCCAB)

DIoU

  好像是为了加快GIoU的收敛速度,DIOU在IOU损失的基础上加一个惩罚项,用来最小化两个检测框中心点之间的标准化距离。用对角线距离把检测框和预测框的中心点距离进行归一化,在IOU值相同的情况下,两个框的中心点归一化距离越小,代表预测框与目标框的对比效果越好。中心点的归一化距离代替了GIOU中的非重合区域占比指标。

在这里插入图片描述
D I o U = ( I o U − p 2 ( A , B ) c 2 ) DIoU= (IoU - \frac {p^2(A,B)}{c^2} ) \quad DIoU=(IoUc2p2(A,B))
   p ( A , B ) p(A,B) p(A,B)是A框与B框中心点坐标的欧式距离,而 c c c则是包住它们的最小方框的对角线距离。

CIoU

  CIoU的作者考虑到bbox回归三要素中的长宽比还没被考虑到计算中,因此,进一步在DIoU的基础上提出了CIoU。其惩罚项如下面公式:
D I o U = ( I o U − p 2 ( A , B ) c 2 − α v ) DIoU= (IoU - \frac {p^2(A,B)}{c^2} -αv) DIoU=(IoUc2p2(A,B)αv)
   其中:
v = 4 π 2 ( a r c t a n w g t h g t − a r c t a n w h ) 2 α = v 1 − I o U + v v = \frac {4}{\pi ^2} (arctan \frac {w^{gt}}{h ^{gt}} - arctan \frac {w}{h})^2 \quad\quad α= \frac {v}{1-IoU+v} v=π24(arctanhgtwgtarctanhw)2α=1IoU+vv

IoU、GIoU、CIoU、DIoU的对比


IoUGIoUDIoUCIoU
优点IOU算法是目标检测中最常用的指标,具有尺度不变性,满足非负性;同一性;对称性;三角不等性等特点。GIOU在基于IOU特性的基础上引入最小外接框解决检测框和真实框没有重叠时loss等于0问题。DIOU在基于IOU特性的基础上考虑到GIOU的缺点,直接回归两个框中心点的欧式距离,加速收敛。CIOU就是在DIOU的基础上增加了检测框尺度的loss,增加了长和宽的loss,这样预测框就会更加的符合真实框。
缺点1.如果两个框不相交,不能反映两个框距离远近
2.无法精确的反映两个框的重合度大小
1.当检测框和真实框出现包含现象的时候GIOU退化成IOU
2.两个框相交时,在水平和垂直方向上收敛慢
回归过程中未考虑Bounding box的纵横比,精确度上尚有进一步提升的空间1. 纵横比描述的是相对值,存在一定的模糊
2.未考虑难易样本的平衡问题

代码


import cv2
import numpy as np
import math

def CountIOU(RecA, RecB, IoU_loss="IoU"):
    """
    :param RecA: 预测框
    :param RecB: 真实框
    :param IoU_loss: 不同IoU计算方法: IoU GIoU DIoU CIoU
    :return: IoU值,要计算IoU loss还要用1减去IoU值
    """

    iou_result = 0
    x1 = max(RecA[0], RecB[0])
    y1 = max(RecA[1], RecB[1])
    x2 = min(RecA[2], RecB[2])
    y2 = min(RecA[3], RecB[3])
    # 计算交集部分面积
    interArea = max(0, x2 - x1) * max(0, y2 - y1 )
    # 计算预测值和真实值的面积
    RecA_Area = max(0, (RecA[2] - RecA[0]) * (RecA[3] - RecA[1]))
    RecB_Area = max(0, (RecB[2] - RecB[0]) * (RecB[3] - RecB[1]))
    ComAB_Area = RecA_Area + RecB_Area - interArea
    # 计算IOU
    iou = interArea / float(ComAB_Area)

    if IoU_loss == "IoU":
        iou_result = iou

    elif IoU_loss == "GIoU":
        # 计算真实框与预测框的最小外接矩形C的面积
        c_x1 = min(RecA[0], RecB[0])
        c_y1 = min(RecA[1], RecB[1])
        c_x2 = max(RecA[2], RecB[2])
        c_y2 = max(RecA[3], RecB[3])
        RecC_Area = max(0, (c_x2 - c_x1) * (c_y2 - c_y1))
        # 计算GIoU
        iou_result = iou - (RecC_Area - ComAB_Area) / float(RecC_Area)

    elif IoU_loss == "DIoU":
        # 计算真实框与预测框中心点的欧式距离
        xA = RecA[0] - RecA[2]
        yA = RecA[1] - RecA[3]
        xB = RecB[0] - RecB[2]
        yB = RecB[1] - RecB[3]
        dist = pow(xA - xB, 2) + pow(yA - yB, 2)
        # 计算真实框与预测框的最小外接矩形对角线的距离
        c_x1 = min(RecA[0], RecB[0])
        c_y1 = min(RecA[1], RecB[1])
        c_x2 = max(RecA[2], RecB[2])
        c_y2 = max(RecA[3], RecB[3])
        diag = pow(c_x1 - c_x2, 2) + pow(c_y1 - c_y2, 2)
        # 计算GIoU
        iou_result = iou - dist / float(diag)

    elif IoU_loss == "CIoU":
        # 计算真实框与预测框中心点的欧式距离
        xA = RecA[0] - RecA[2]
        yA = RecA[1] - RecA[3]
        xB = RecB[0] - RecB[2]
        yB = RecB[1] - RecB[3]
        dist = pow(xA - xB, 2) + pow(yA - yB, 2)
        # 计算真实框与预测框的最小外接矩形对角线的距离
        c_x1 = min(RecA[0], RecB[0])
        c_y1 = min(RecA[1], RecB[1])
        c_x2 = max(RecA[2], RecB[2])
        c_y2 = max(RecA[3], RecB[3])
        diag = pow(c_x1 - c_x2, 2) + pow(c_y1 - c_y2, 2)
        # 计算真实框和预测框的高宽
        w_p = max(0, RecA[2] - RecA[0])
        h_p = max(0, RecA[3] - RecA[1])
        w_gt = max(0, RecB[2] - RecB[0])
        h_gt = max(0, RecB[3] - RecB[1])
        # 计算参数 v 和 α
        v = ( 4 * pow( (math.atan(w_gt/float(h_gt)) - math.atan(w_p/float(h_p))), 2) ) / pow(math.pi, 2)
        a = v / (( 1 - iou) + v)
        #计算CIoU
        iou_result = iou - (pow(dist,2) / float(pow(diag,2))) - (a*v)

    else:
        raise NotImplementedError('IoU_loss method [%s] is not implemented' % IoU_loss)

    return iou_result


img = np.zeros((512, 512, 3), np.uint8)
img.fill(255)

RecA = [50, 50, 300, 300]
RecB = [90, 90, 320, 320]

cv2.rectangle(img, (RecA[0], RecA[1]), (RecA[2], RecA[3]), (0, 255, 0), 5)
cv2.rectangle(img, (RecB[0], RecB[1]), (RecB[2], RecB[3]), (255, 0, 0), 5)

IOU = CountIOU(RecA, RecB, IoU_loss="DIoU")
font = cv2.FONT_HERSHEY_SIMPLEX

cv2.putText(img, "IOU = %.2f" % IOU, (130, 190), font, 0.8, (0, 0, 0), 2)

cv2.imshow("image", img)
cv2.waitKey()
cv2.destroyAllWindows()

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Fire丶Chicken

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

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

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

打赏作者

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

抵扣说明:

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

余额充值