|
2 | 2 | import numba
|
3 | 3 | import numpy as np
|
4 | 4 | import torch
|
5 |
| -from mmcv.ops import nms_bev as nms_gpu |
6 |
| -from mmcv.ops import nms_normal_bev as nms_normal_gpu |
| 5 | +from mmcv.ops import nms, nms_rotated |
| 6 | + |
| 7 | +from ..bbox import xywhr2xyxyr |
7 | 8 |
|
8 | 9 |
|
9 | 10 | def box3d_multiclass_nms(mlvl_bboxes,
|
@@ -61,9 +62,9 @@ def box3d_multiclass_nms(mlvl_bboxes,
|
61 | 62 | _bboxes_for_nms = mlvl_bboxes_for_nms[cls_inds, :]
|
62 | 63 |
|
63 | 64 | if cfg.use_rotate_nms:
|
64 |
| - nms_func = nms_gpu |
| 65 | + nms_func = nms_bev |
65 | 66 | else:
|
66 |
| - nms_func = nms_normal_gpu |
| 67 | + nms_func = nms_normal_bev |
67 | 68 |
|
68 | 69 | selected = nms_func(_bboxes_for_nms, _scores, cfg.nms_thr)
|
69 | 70 | _mlvl_bboxes = mlvl_bboxes[cls_inds, :]
|
@@ -224,3 +225,63 @@ def circle_nms(dets, thresh, post_max_size=83):
|
224 | 225 | return keep[:post_max_size]
|
225 | 226 |
|
226 | 227 | return keep
|
| 228 | + |
| 229 | + |
| 230 | +# This function duplicates functionality of mmcv.ops.iou_3d.nms_bev |
| 231 | +# from mmcv<=1.5, but using cuda ops from mmcv.ops.nms.nms_rotated. |
| 232 | +# Nms api will be unified in mmdetection3d one day. |
| 233 | +def nms_bev(boxes, scores, thresh, pre_max_size=None, post_max_size=None): |
| 234 | + """NMS function GPU implementation (for BEV boxes). The overlap of two |
| 235 | + boxes for IoU calculation is defined as the exact overlapping area of the |
| 236 | + two boxes. In this function, one can also set ``pre_max_size`` and |
| 237 | + ``post_max_size``. |
| 238 | +
|
| 239 | + Args: |
| 240 | + boxes (torch.Tensor): Input boxes with the shape of [N, 5] |
| 241 | + ([x1, y1, x2, y2, ry]). |
| 242 | + scores (torch.Tensor): Scores of boxes with the shape of [N]. |
| 243 | + thresh (float): Overlap threshold of NMS. |
| 244 | + pre_max_size (int, optional): Max size of boxes before NMS. |
| 245 | + Default: None. |
| 246 | + post_max_size (int, optional): Max size of boxes after NMS. |
| 247 | + Default: None. |
| 248 | +
|
| 249 | + Returns: |
| 250 | + torch.Tensor: Indexes after NMS. |
| 251 | + """ |
| 252 | + assert boxes.size(1) == 5, 'Input boxes shape should be [N, 5]' |
| 253 | + order = scores.sort(0, descending=True)[1] |
| 254 | + if pre_max_size is not None: |
| 255 | + order = order[:pre_max_size] |
| 256 | + boxes = boxes[order].contiguous() |
| 257 | + # xyxyr -> back to xywhr |
| 258 | + # note: better skip this step before nms_bev call in the future |
| 259 | + boxes = torch.stack( |
| 260 | + ((boxes[:, 0] + boxes[:, 2]) / 2, (boxes[:, 1] + boxes[:, 3]) / 2, |
| 261 | + boxes[:, 2] - boxes[:, 0], boxes[:, 3] - boxes[:, 1], boxes[:, 4]), |
| 262 | + dim=-1) |
| 263 | + |
| 264 | + keep = nms_rotated(boxes, scores, thresh)[1] |
| 265 | + if post_max_size is not None: |
| 266 | + keep = keep[:post_max_size] |
| 267 | + return keep |
| 268 | + |
| 269 | + |
| 270 | +# This function duplicates functionality of mmcv.ops.iou_3d.nms_normal_bev |
| 271 | +# from mmcv<=1.5, but using cuda ops from mmcv.ops.nms.nms. |
| 272 | +# Nms api will be unified in mmdetection3d one day. |
| 273 | +def nms_normal_bev(boxes, scores, thresh): |
| 274 | + """Normal NMS function GPU implementation (for BEV boxes). The overlap of |
| 275 | + two boxes for IoU calculation is defined as the exact overlapping area of |
| 276 | + the two boxes WITH their yaw angle set to 0. |
| 277 | +
|
| 278 | + Args: |
| 279 | + boxes (torch.Tensor): Input boxes with shape (N, 5). |
| 280 | + scores (torch.Tensor): Scores of predicted boxes with shape (N). |
| 281 | + thresh (float): Overlap threshold of NMS. |
| 282 | +
|
| 283 | + Returns: |
| 284 | + torch.Tensor: Remaining indices with scores in descending order. |
| 285 | + """ |
| 286 | + assert boxes.shape[1] == 5, 'Input boxes shape should be [N, 5]' |
| 287 | + return nms(xywhr2xyxyr(boxes)[:, :-1], scores, thresh)[1] |
0 commit comments