Safemotion Lib
Loading...
Searching...
No Matches
iou_calculator.py
Go to the documentation of this file.
1import torch
2
3def fp16_clamp(x, min=None, max=None):
4 if not x.is_cuda and x.dtype == torch.float16:
5 # clamp for cpu float16, tensor fp16 has no clamp implementation
6 return x.float().clamp(min, max).half()
7
8 return x.clamp(min, max)
9
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 # Either the boxes are empty or the length of boxes' last dimension is 4
14 assert (bboxes1.size(-1) == 4 or bboxes1.size(0) == 0)
15 assert (bboxes2.size(-1) == 4 or bboxes2.size(0) == 0)
16
17 # Batch dim must be the same
18 # Batch dim: (B1, B2, ... Bn)
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]) # [B, rows, 2]
40 rb = torch.min(bboxes1[..., 2:], bboxes2[..., 2:]) # [B, rows, 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]) # [B, rows, cols, 2]
55 rb = torch.min(bboxes1[..., :, None, 2:],
56 bboxes2[..., None, :, 2:]) # [B, rows, cols, 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 # calculate gious
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
bbox_overlaps(bboxes1, bboxes2, mode='iou', is_aligned=False, eps=1e-6)
fp16_clamp(x, min=None, max=None)