code: def non_max_suppression(
      boxes: NdarrayOrTensor,
      scores: NdarrayOrTensor,
      nms_thresh: float,
      max_proposals: int = -1,
      box_overlap_metric: Callable = box_iou,
  ) -> NdarrayOrTensor:
      """
      Non-maximum suppression (NMS).
  
      Args:
          boxes: bounding boxes, Nx4 or Nx6 torch tensor or ndarray. The box mode is assumed to be ``StandardMode``
          scores: prediction scores of the boxes, sized (N,). This function keeps boxes with higher scores.
          nms_thresh: threshold of NMS. Discards all overlapping boxes with box_overlap > nms_thresh.
          max_proposals: maximum number of boxes it keeps.
              If ``max_proposals`` = -1, there is no limit on the number of boxes that are kept.
          box_overlap_metric: the metric to compute overlap between boxes.
  
      Returns:
          Indexes of ``boxes`` that are kept after NMS.
  
      Example:
          .. code-block:: python
  
              boxes = torch.ones(10,6)
              scores = torch.ones(10)
              keep = non_max_suppression(boxes, scores, num_thresh=0.1)
              boxes_after_nms = boxes[keep]
      """
  
      # returns empty array if boxes is empty
      if boxes.shape[0] == 0:
          return convert_to_dst_type(
              src=np.array([]), dst=boxes, dtype=torch.long
          )[0]
  
      if boxes.shape[0] != scores.shape[0]:
          raise ValueError(
              f"boxes and scores should have same length, got boxes shape {boxes.shape}, scores shape {scores.shape}"
          )
  
      # convert numpy to tensor if needed
      boxes_t, *_ = convert_data_type(boxes, torch.Tensor)
      scores_t, *_ = convert_to_dst_type(scores, boxes_t)
  
      # sort boxes in descending order according to the scores
      sort_idxs = torch.argsort(scores_t, dim=0, descending=True)
      boxes_sort = deepcopy(boxes_t)[sort_idxs, :]
  
      # initialize the list of picked indexes
      pick = []
      idxs = torch.Tensor(list(range(0, boxes_sort.shape[0]))).to(
          device=boxes_t.device, dtype=torch.long
      )
  
      # keep looping while some indexes still remain in the indexes list
      while len(idxs) > 0:
          # pick the first index in the indexes list and add the index value to the list of picked indexes
          i = int(idxs[0].item())
          pick.append(i)
          if len(pick) >= max_proposals >= 1:
              break
  
          # compute the IoU between the rest of the boxes and the box just picked
          box_overlap = box_overlap_metric(
              boxes_sort[idxs, :], boxes_sort[i : i + 1, :]
          )
  
          # keep only indexes from the index list that have overlap < nms_thresh
          to_keep_idx = (box_overlap <= nms_thresh).flatten()
          to_keep_idx[0] = False  # always remove idxs[0]
          idxs = idxs[to_keep_idx]
  
      # return only the bounding boxes that were picked using the integer data type
      pick_idx = sort_idxs[pick]
  
      # convert tensor back to numpy if needed
      return convert_to_dst_type(
          src=pick_idx, dst=boxes, dtype=pick_idx.dtype
      )[0]
  
imports: from __future__ import annotations
  import inspect
  import warnings
  from abc import ABC, abstractmethod
  from collections.abc import Callable, Sequence
  from copy import deepcopy
  import numpy
  import torch
  from monai.config.type_definitions import NdarrayOrTensor, NdarrayTensor
  from monai.utils import look_up_option
  from monai.utils.enums import BoxModeName
  from monai.utils.type_conversion import convert_data_type, convert_to_dst_type
label_desc: Use image node_id 17 for calling a global function with example usage: non_max_suppression(boxes, scores, nms_thresh, max_proposals, box_overlap_metric) and returns: convert_to_dst_type, convert_to_dst_type