目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss
https://mp.weixin.qq.com/s?__biz=MzI5MDUyMDIxNA==&mid=2247493294&idx=1&sn=d64822f1c2ca25901f7b707d78028364&chksm=ec1c0b57db6b82414c9177a13da5c1cceda8963785e22cb777b43892608c9ce71afc90c8d0c1&token=1513639846&lang=zh_CN#rd

代码

https://sourcegraph.com/github.com/Zzh-tju/DIoU-darknet/-/blob/src/box.c#L243

  1. def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False):
  2. # Get the coordinates of bounding boxes
  3. if x1y1x2y2: # x1, y1, x2, y2 = box1
  4. b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]
  5. b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]
  6. else: # x, y, w, h = box1
  7. b1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2
  8. b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2
  9. b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2
  10. b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2
  11. # Intersection area
  12. inter = (min(b1_x2, b2_x2) - max(b1_x1, b2_x1)).clamp(0) * \
  13. (min(b1_y2, b2_y2) - max(b1_y1, b2_y1)).clamp(0)
  14. # Union Area
  15. w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1
  16. w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1
  17. union = (w1 * h1 + 1e-16) + w2 * h2 - inter
  18. iou = inter / union # iou
  19. if GIoU or DIoU or CIoU:
  20. cw = max(b1_x2, b2_x2) - min(b1_x1, b2_x1) # convex (smallest enclosing box) width
  21. ch = max(b1_y2, b2_y2) - min(b1_y1, b2_y1) # convex height
  22. if GIoU: # Generalized IoU https://arxiv.org/pdf/1902.09630.pdf
  23. c_area = cw * ch + 1e-16 # convex area
  24. return iou - (c_area - union) / c_area # GIoU
  25. if DIoU or CIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1
  26. # convex diagonal squared
  27. c2 = cw ** 2 + ch ** 2 + 1e-16
  28. # centerpoint distance squared
  29. rho2 = ((b2_x1 + b2_x2) - (b1_x1 + b1_x2)) ** 2 / 4 + ((b2_y1 + b2_y2) - (b1_y1 + b1_y2)) ** 2 / 4
  30. if DIoU:
  31. return iou - rho2 / c2 # DIoU
  32. elif CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47
  33. v = (4 / math.pi ** 2) * pow(atan(w2 / h2) - atan(w1 / h1), 2)
  34. with no_grad():
  35. alpha = v / (1 - iou + v)
  36. return iou - (rho2 / c2 + v * alpha) # CIoU
  37. return iou