代码地址:https://arxiv.org/pdf/1608.01471.pdf
def IOU(box1, box2):
"""
iou loss
:param box1: tensor [batch, w, h, num_anchor, 4], xywh 预测值
:param box2: tensor [batch, w, h, num_anchor, 4], xywh 真实值
:return: tensor [batch, w, h, num_anchor, 1]
"""
box1_xy, box1_wh = box1[..., :2], box1[..., 2:4]
box1_wh_half = box1_wh / 2.
box1_mines = box1_xy - box1_wh_half
box1_maxes = box1_xy + box1_wh_half
box2_xy, box2_wh = box2[..., :2], box2[..., 2:4]
box2_wh_half = box2_wh / 2.
box2_mines = box2_xy - box2_wh_half
box2_maxes = box2_xy + box2_wh_half
# 求真实值和预测值所有的iou
intersect_mines = torch.max(box1_mines, box2_mines)
intersect_maxes = torch.min(box1_maxes, box2_maxes)
intersect_wh = torch.max(intersect_maxes-intersect_mines, torch.zeros_like(intersect_maxes))
intersect_area = intersect_wh[..., 0]*intersect_wh[..., 1]
box1_area = box1_wh[..., 0]*box1_wh[..., 1]
box2_area = box2_wh[..., 0]*box2_wh[..., 1]
union_area = box1_area+box2_area-intersect_area
iou = intersect_area / torch.clamp(union_area, min=1e-6)
return iou
代码地址:https://arxiv.org/abs/1902.09630
def GIOU(box1, box2):
"""
giou loss
:param box1: tensor [batch, w, h, num_anchor, 4], xywh 预测值
:param box2: tensor [batch, w, h, num_anchor, 4], xywh 真实值
:return: tensor [batch, w, h, num_anchor, 1]
"""
b1_x1, b1_x2 = box1[..., 0] - box1[..., 2] / 2, box1[..., 0] + box1[..., 2] / 2
b1_y1, b1_y2 = box1[..., 1] - box1[..., 3] / 2, box1[..., 1] + box1[..., 3] / 2
b2_x1, b2_x2 = box2[..., 0] - box2[..., 2] / 2, box2[..., 0] + box2[..., 2] / 2
b2_y1, b2_y2 = box2[..., 1] - box2[..., 3] / 2, box2[..., 1] + box2[..., 3] / 2
box1_xy, box1_wh = box1[..., :2], box1[..., 2:4]
box1_wh_half = box1_wh / 2.
box1_mines = box1_xy - box1_wh_half
box1_maxes = box1_xy + box1_wh_half
box2_xy, box2_wh = box2[..., :2], box2[..., 2:4]
box2_wh_half = box2_wh / 2.
box2_mines = box2_xy - box2_wh_half
box2_maxes = box2_xy + box2_wh_half
# 求真实值和预测值所有的iou
intersect_mines = torch.max(box1_mines, box2_mines)
intersect_maxes = torch.min(box1_maxes, box2_maxes)
intersect_wh = torch.max(intersect_maxes-intersect_mines, torch.zeros_like(intersect_maxes))
intersect_area = intersect_wh[..., 0]*intersect_wh[..., 1]
box1_area = box1_wh[..., 0]*box1_wh[..., 1]
box2_area = box2_wh[..., 0]*box2_wh[..., 1]
union_area = box1_area+box2_area-intersect_area
iou = intersect_area / torch.clamp(union_area, min=1e-6)
# 计算最小包围框的宽和高
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)
c_area = cw * ch + 1e-16 # convex area
return iou - (c_area - union_area) / c_area
代码地址:https://arxiv.org/pdf/1911.08287.pdf
def DIOU(box1, box2):
"""
diou loss
:param box1: tensor [batch, w, h, num_anchor, 4], xywh 预测值
:param box2: tensor [batch, w, h, num_anchor, 4], xywh 真实值
:return: tensor [batch, w, h, num_anchor, 1]
"""
b1_x1, b1_x2 = box1[..., 0] - box1[..., 2] / 2, box1[..., 0] + box1[..., 2] / 2
b1_y1, b1_y2 = box1[..., 1] - box1[..., 3] / 2, box1[..., 1] + box1[..., 3] / 2
b2_x1, b2_x2 = box2[..., 0] - box2[..., 2] / 2, box2[..., 0] + box2[..., 2] / 2
b2_y1, b2_y2 = box2[..., 1] - box2[..., 3] / 2, box2[..., 1] + box2[..., 3] / 2
box1_xy, box1_wh = box1[..., :2], box1[..., 2:4]
box1_wh_half = box1_wh / 2.
box1_mines = box1_xy - box1_wh_half
box1_maxes = box1_xy + box1_wh_half
box2_xy, box2_wh = box2[..., :2], box2[..., 2:4]
box2_wh_half = box2_wh / 2.
box2_mines = box2_xy - box2_wh_half
box2_maxes = box2_xy + box2_wh_half
# 求真实值和预测值所有的iou
intersect_mines = torch.max(box1_mines, box2_mines)
intersect_maxes = torch.min(box1_maxes, box2_maxes)
intersect_wh = torch.max(intersect_maxes-intersect_mines, torch.zeros_like(intersect_maxes))
intersect_area = intersect_wh[..., 0]*intersect_wh[..., 1]
box1_area = box1_wh[..., 0]*box1_wh[..., 1]
box2_area = box2_wh[..., 0]*box2_wh[..., 1]
union_area = box1_area+box2_area-intersect_area
iou = intersect_area / torch.clamp(union_area, min=1e-6)
# 计算最小包围框的宽和高
cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1) # convex (smallest enclosing box) width
ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)
c2 = cw ** 2 + ch ** 2 + 1e-16
# 两个框中心点距离的平方
rho2 = ((b2_x1 + b2_x2) - (b1_x1 + b1_x2)) ** 2 / 4 + ((b2_y1 + b2_y2) - (b1_y1 + b1_y2)) ** 2 / 4
return iou - rho2 / c2
def CIOU(box1, box2):
"""
ciou loss
:param box1: tensor [batch, w, h, num_anchor, 4], xywh 预测值
:param box2: tensor [batch, w, h, num_anchor, 4], xywh 真实值
:return: tensor [batch, w, h, num_anchor, 1]
"""
box1_xy, box1_wh = box1[..., :2], box1[..., 2:4]
box1_wh_half = box1_wh / 2.
box1_mines = box1_xy - box1_wh_half
box1_maxes = box1_xy + box1_wh_half
box2_xy, box2_wh = box2[..., :2], box2[..., 2:4]
box2_wh_half = box2_wh / 2.
box2_mines = box2_xy - box2_wh_half
box2_maxes = box2_xy + box2_wh_half
# 求真实值和预测值所有的iou
intersect_mines = torch.max(box1_mines, box2_mines)
intersect_maxes = torch.min(box1_maxes, box2_maxes)
intersect_wh = torch.max(intersect_maxes-intersect_mines, torch.zeros_like(intersect_maxes))
intersect_area = intersect_wh[..., 0]*intersect_wh[..., 1]
box1_area = box1_wh[..., 0]*box1_wh[..., 1]
box2_area = box2_wh[..., 0]*box2_wh[..., 1]
union_area = box1_area+box2_area-intersect_area
iou = intersect_area / torch.clamp(union_area, min=1e-6)
# 计算中心的差距
center_distance = torch.sum(torch.pow((box1_xy-box2_xy), 2), dim=-1)
# 找到包裹两个框的最小框的左上角和右下角
enclose_mines = torch.min(box1_mines, box2_mines)
enclose_maxes = torch.max(box1_maxes, box2_maxes)
enclose_wh = torch.max(enclose_maxes-enclose_mines, torch.zeros_like(intersect_maxes))
# 计算对角线距离
enclose_diagonal = torch.sum(torch.pow(enclose_wh, 2), dim=-1)
ciou = iou - 1. * center_distance / torch.clamp(enclose_diagonal, min=1e-6)
v = (4/(math.pi**2))*torch.pow((torch.atan(box1_wh[..., 0]/torch.clamp(box1_wh[..., 1], min=1e-6))-torch.atan(box2_wh[..., 0]/torch.clamp(box2_wh[..., 1], min=1e-6))), 2)
alpha = v / torch.clamp((1.-iou+v), min=1e-6)
ciou = ciou - alpha * v
return ciou