```'''
计算两个box的中心点距离d
'''
# d = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
d = math.sqrt((pred[:, -1] - target[:, -1]) ** 2 + (pred[:, -2] - target[:, -2]) ** 2)
# 左边x
pred_l = pred[:, -1] - pred[:, -1] / 2
target_l = target[:, -1] - target[:, -1] / 2
# 上边y
pred_t = pred[:, -2] - pred[:, -2] / 2
target_t = target[:, -2] - target[:, -2] / 2
# 右边x
pred_r = pred[:, -1] + pred[:, -1] / 2
target_r = target[:, -1] + target[:, -1] / 2
# 下边y
pred_b = pred[:, -2] + pred[:, -2] / 2
target_b = target[:, -2] + target[:, -2] / 2
'''
计算两个box的bound的对角线距离
'''
bound_l = torch.min(pred_l, target_l)  # left
bound_r = torch.max(pred_r, target_r)  # right
bound_t = torch.min(pred_t, target_t)  # top
bound_b = torch.max(pred_b, target_b)  # bottom
c = math.sqrt((bound_r - bound_l) ** 2 + (bound_b - bound_t) ** 2)
dloss = iou - (d ** 2) / (c ** 2)
loss = 1 - dloss.clamp(min=-1.0, max=1.0)```

pred[:,:2]第一个：表示多个图片，第二个 :2 表示前两个数值，代表矩形框中心点(Y，X)

pred[:,2:]第一个：表示多个图片，第二个 2: 表示 后 两个数值，代表矩形框长宽(H，W)

target[:,:2]同理，

d =

d是两个预测矩形中心点的距离

A 两个框中心对齐时候，d/c=0，iou可能0-1

A 两个框相距很远时，d/c=1，iou=0

dloss=iou-d/c属于-1到1

YOLOX是下载自

GitHub – Megvii-BaseDetection/YOLOX: YOLOX is a high-performance anchor-free YOLO, exceeding yolov3~v5 with MegEngine, ONNX, TensorRT, ncnn, and OpenVINO supported. Documentation: https://yolox.readthedocs.io/ YOLOX is a high-performance anchor-free YOLO, exceeding yolov3~v5 with MegEngine, ONNX, TensorRT, ncnn, and OpenVINO supported. Documentation: https://yolox.readthedocs.io/ – GitHub – Megvii-BaseDetection/YOLOX: YOLOX is a high-performance anchor-free YOLO, exceeding yolov3~v5 with MegEngine, ONNX, TensorRT, ncnn, and OpenVINO supported. Documentation: https://yolox.readthedocs.io/ https://github.com/Megvii-BaseDetection/YOLOX

```class IOUloss(nn.Module):
def __init__(self, reduction="none", loss_type="iou"):
super(IOUloss, self).__init__()
self.reduction = reduction
self.loss_type = loss_type
def forward(self, pred, target):
assert pred.shape[0] == target.shape[0]
pred = pred.view(-1, 4)
target = target.view(-1, 4)
tl = torch.max(
(pred[:, :2] - pred[:, 2:] / 2), (target[:, :2] - target[:, 2:] / 2)
)
# pred target都是[H,W,Y,X]
# (Y,X)-(H,W) 左上角
br = torch.min(
(pred[:, :2] + pred[:, 2:] / 2), (target[:, :2] + target[:, 2:] / 2)
)
# (X,Y)+(H,W) 右下角
area_p = torch.prod(pred[:, 2:], 1)  # HxW
area_g = torch.prod(target[:, 2:], 1)
en = (tl < br).type(tl.type()).prod(dim=1)
area_i = torch.prod(br - tl, 1) * en
area_u = area_p + area_g - area_i
iou = (area_i) / (area_u + 1e-16)
if self.loss_type == "iou":
loss = 1 - iou ** 2
elif self.loss_type == "giou":
c_tl = torch.min(
(pred[:, :2] - pred[:, 2:] / 2), (target[:, :2] - target[:, 2:] / 2)
)
c_br = torch.max(
(pred[:, :2] + pred[:, 2:] / 2), (target[:, :2] + target[:, 2:] / 2)
)
area_c = torch.prod(c_br - c_tl, 1)
giou = iou - (area_c - area_u) / area_c.clamp(1e-16)
loss = 1 - giou.clamp(min=-1.0, max=1.0)
# pred[:, :2]  pred[:, 2:]
# (Y,X)        (H,W)
# target[:, :2]  target[:, 2:]
# (Y,X)        (H,W)
elif self.loss_type == "diou":
'''
计算两个box的中心点距离d
'''
# d = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
d = math.sqrt((pred[:, -1] - target[:, -1]) ** 2 + (pred[:, -2] - target[:, -2]) ** 2)
# 左边x
pred_l = pred[:, -1] - pred[:, -1] / 2
target_l = target[:, -1] - target[:, -1] / 2
# 上边y
pred_t = pred[:, -2] - pred[:, -2] / 2
target_t = target[:, -2] - target[:, -2] / 2
# 右边x
pred_r = pred[:, -1] + pred[:, -1] / 2
target_r = target[:, -1] + target[:, -1] / 2
# 下边y
pred_b = pred[:, -2] + pred[:, -2] / 2
target_b = target[:, -2] + target[:, -2] / 2
'''
计算两个box的bound的对角线距离
'''
bound_l = torch.min(pred_l, target_l)  # left
bound_r = torch.max(pred_r, target_r)  # right
bound_t = torch.min(pred_t, target_t)  # top
bound_b = torch.max(pred_b, target_b)  # bottom
c = math.sqrt((bound_r - bound_l) ** 2 + (bound_b - bound_t) ** 2)
dloss = iou - (d ** 2) / (c ** 2)
loss = 1 - dloss.clamp(min=-1.0, max=1.0)
# Step1
# def DIoU(a, b):
# d = a.center_distance(b)
# c = a.bound_diagonal_distance(b)
# return IoU(a, b) - (d ** 2) / (c ** 2)
# Step2-1
# def center_distance(self, other):
#    '''
#    计算两个box的中心点距离
#    '''
#    return euclidean_distance(self.center, other.center)
# Step2-2
# def euclidean_distance(p1, p2):
#    '''
#    计算两个点的欧式距离
#    '''
#     x1, y1 = p1
#    x2, y2 = p2
#    return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
# Step3
# def bound_diagonal_distance(self, other):
#    '''
#    计算两个box的bound的对角线距离
#    '''
#    bound = self.boundof(other)
#    return euclidean_distance((bound.x, bound.y), (bound.r, bound.b))
# Step3-2
# def boundof(self, other):
#    '''
#    计算box和other的边缘外包框，使得2个box都在框内的最小矩形
#    '''
#    xmin = min(self.x, other.x)
#    ymin = min(self.y, other.y)
#    xmax = max(self.r, other.r)
#    ymax = max(self.b, other.b)
#    return BBox(xmin, ymin, xmax, ymax)
# Step3-3
# def euclidean_distance(p1, p2):
#    '''
#    计算两个点的欧式距离
#    '''
#     x1, y1 = p1
#    x2, y2 = p2
#    return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)

if self.reduction == "mean":
loss = loss.mean()
elif self.reduction == "sum":
loss = loss.sum()
return loss```

GitHub – Megvii-BaseDetection/YOLOX: YOLOX is a high-performance anchor-free YOLO, exceeding yolov3~v5 with MegEngine, ONNX, TensorRT, ncnn, and OpenVINO supported. Documentation: https://yolox.readthedocs.io/