10def bbox_overlaps(bboxes1, bboxes2, mode='iou', is_aligned=False, eps=1e-6):
11
12 assert mode in ['iou', 'iof', 'giou'], f'Unsupported mode {mode}'
13
14 assert (bboxes1.size(-1) == 4 or bboxes1.size(0) == 0)
15 assert (bboxes2.size(-1) == 4 or bboxes2.size(0) == 0)
16
17
18
19 assert bboxes1.shape[:-2] == bboxes2.shape[:-2]
20 batch_shape = bboxes1.shape[:-2]
21
22 rows = bboxes1.size(-2)
23 cols = bboxes2.size(-2)
24 if is_aligned:
25 assert rows == cols
26
27 if rows * cols == 0:
28 if is_aligned:
29 return bboxes1.new(batch_shape + (rows, ))
30 else:
31 return bboxes1.new(batch_shape + (rows, cols))
32
33 area1 = (bboxes1[..., 2] - bboxes1[..., 0]) * (
34 bboxes1[..., 3] - bboxes1[..., 1])
35 area2 = (bboxes2[..., 2] - bboxes2[..., 0]) * (
36 bboxes2[..., 3] - bboxes2[..., 1])
37
38 if is_aligned:
39 lt = torch.max(bboxes1[..., :2], bboxes2[..., :2])
40 rb = torch.min(bboxes1[..., 2:], bboxes2[..., 2:])
41
42 wh = fp16_clamp(rb - lt, min=0)
43 overlap = wh[..., 0] * wh[..., 1]
44
45 if mode in ['iou', 'giou']:
46 union = area1 + area2 - overlap
47 else:
48 union = area1
49 if mode == 'giou':
50 enclosed_lt = torch.min(bboxes1[..., :2], bboxes2[..., :2])
51 enclosed_rb = torch.max(bboxes1[..., 2:], bboxes2[..., 2:])
52 else:
53 lt = torch.max(bboxes1[..., :, None, :2],
54 bboxes2[..., None, :, :2])
55 rb = torch.min(bboxes1[..., :, None, 2:],
56 bboxes2[..., None, :, 2:])
57
58 wh = fp16_clamp(rb - lt, min=0)
59 overlap = wh[..., 0] * wh[..., 1]
60
61 if mode in ['iou', 'giou']:
62 union = area1[..., None] + area2[..., None, :] - overlap
63 else:
64 union = area1[..., None]
65 if mode == 'giou':
66 enclosed_lt = torch.min(bboxes1[..., :, None, :2],
67 bboxes2[..., None, :, :2])
68 enclosed_rb = torch.max(bboxes1[..., :, None, 2:],
69 bboxes2[..., None, :, 2:])
70
71 eps = union.new_tensor([eps])
72 union = torch.max(union, eps)
73 ious = overlap / union
74 if mode in ['iou', 'iof']:
75 return ious
76
77 enclose_wh = fp16_clamp(enclosed_rb - enclosed_lt, min=0)
78 enclose_area = enclose_wh[..., 0] * enclose_wh[..., 1]
79 enclose_area = torch.max(enclose_area, eps)
80 gious = ious - (enclose_area - union) / enclose_area
81 return gious