IOU、GIOU、DIOU、CIOU原理及代码介绍

一、IOU

论文:UnitBox: An Advanced Object Detection Network

定义

IOU的全称是Intersection over Union,即我们常说的交并比。IOU可以用作目标检测中正负样本的分配依据,也可用于衡量预测框与GT框之间的差异(目标检测中的AP(average precision)就是基于IOU求得的)。IOU的计算公式也很简单,即两个边界框的交集与并集的比值,

特点

  • 非负性、同一性、对称性、尺度不变性
  • 无法精确反映两个边界框的重合度

  • 如果两个边界框不相交,则无法反映两个边界框的差距

代码示例

import torch


def cal_iou(box1, box2, eps=1e-7):
    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]
    # Intersection area
    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)
    # Union Area
    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 = inter / union

    return iou

二、GIOU

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

定义

为了克服IOU的缺点,GIOU在IOU的基础上做了修改,公式如下,

其中,C:包含边界框A、B的最小外接矩形(如下图中的绿色矩形框)

特点

  • 在IOU的基础上引入最小外接矩形框以解决预测框和GT框之间没有交集时IOU为0的问题
  • GIoU不仅关注重叠区域,还关注其他的非重合区域,能更好的反映两者的重合度
  • GIOU的取值范围是[-1,1],在两者重合的时候取最大值1,在两者无交集且无限远的时候取最小值-1
  • 当预测框和GT框出现包含现象时,GIOU退化成IOU

代码示例

import torch


def cal_giou(box1, box2, eps=1e-7):
    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]
    # Intersection area
    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)
    # Union Area
    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 = inter / union

    cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # smallest enclosing box width
    ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # smallest enclosing box height
    c_area = cw * ch + eps  # convex area
    
    giou = iou - (c_area - union) / c_area

    return giou

三、DIOU

论文:Distance-IoULoss:FasterandBetterLearningforBoundingBoxRegression

定义

为了克服GIOU的缺点,DIOU在IOU的基础上做了改进,公式如下,

其中,\rho ^{2}:两点间的欧式距离平方和,center_{A}center_{B}:边界框A、B的中心点坐标,c:包含A、B的最小外接矩形框的对角线长度 

特点

  • DIOU可以直接优化2个边界框之间的距离,比GIOU Loss收敛更快
  • 如果两个边界框完美重合,d=0,IOU=1,DIOU=1-0=1。如果两个边界框相距很远,\frac{d^{2}}{c^{2}}趋近于1,IOU=0, DIOU=0-1=-1。因此,DIOU的取值范围也是[-1,1]
  • 即使在一个框包含另一个框的情况下,c值不变,但d值也可以进行有效度量
  • 当两个边界框的中心点重合时,可能存在c与d都不变的情况

代码示例

import torch


def cal_diou(box1, box2, eps=1e-7):
    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]
    # Intersection area
    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)
    # Union Area
    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 = inter / union

    cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # smallest enclosing box width
    ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # smallest enclosing box height
    c2 = cw ** 2 + ch ** 2 + eps  # the diagonal of smallest enclosing box
    rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4  # center distance squared
    
    diou = iou - rho2 / c2

    return diou

四、CIOU

Complete IOU

定义

CIOU就是在DIOU的基础上增加了边界框的宽高比,公式如下,

​​​​​​因此CIOU的三项恰好对应IOU、中心点距离与最小外接矩形框对角线距离的比值、两个边界框宽高比之间的差距

特点

  • CIOU就是在DIOU的基础上增加了边界框的宽高比,使预测框更加贴近GT框
  • 边界框的宽高比描述的是相对值,存在一定的模糊

代码示例

import torch
import math


def cal_ciou(box1, box2, eps=1e-7):
    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]
    # Intersection area
    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)
    # Union Area
    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 = inter / union

    cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # smallest enclosing box width
    ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # smallest enclosing box height
    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  # center distance squared
    
    v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / (h2 + eps)) - torch.atan(w1 / (h1 + eps)), 2)

    with torch.no_grad():
        alpha = v / (v - iou + (1 + eps))
    ciou = iou - (rho2 / c2 + v * alpha)

    return ciou

参考文章

https://www.cnblogs.com/wujianming-110117/p/13019343.html

IOU、GIOU、DIOU、CIOU损失函数详解 - 知乎

IOU、GIOU、DIOU、CIOU详解及代码实现_小小小~的博客-CSDN博客

IoU系列(IoU, GIoU, DIoU, CIoU)_ciou公式_PoomHey的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/qq_38964360/article/details/131538126
今日推荐