一、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的基础上做了改进,公式如下,
其中,:两点间的欧式距离平方和,、:边界框A、B的中心点坐标,:包含A、B的最小外接矩形框的对角线长度
特点
- DIOU可以直接优化2个边界框之间的距离,比GIOU Loss收敛更快
- 如果两个边界框完美重合,d=0,IOU=1,DIOU=1-0=1。如果两个边界框相距很远,趋近于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