code: def non_max_suppression(
      prediction,
      conf_thres=0.1,
      iou_thres=0.6,
      multi_label=True,
      classes=None,
      agnostic=False,
      max_num=100,
  ):
      """
      Performs  Non-Maximum Suppression on inference results
  
      param: prediction[batch, num_anchors, (num_classes+1+4) x num_anchors]
      Returns detections with shape:
          nx6 (x1, y1, x2, y2, conf, cls)
      """
  
      # Settings
      merge = False  # merge for best mAP
      min_wh, max_wh = (
          2,
          4096,
      )  # (pixels) minimum and maximum box width and height
      time_limit = 10.0  # seconds to quit after
  
      t = time.time()
      nc = prediction[0].shape[1] - 5  # number of classes
      multi_label &= nc > 1  # multiple labels per box
      output = [None] * prediction.shape[0]
      for xi, x in enumerate(
          prediction
      ):  # image index, image inference 遍历每张图片
          # Apply constraints
          x = x[
              x[:, 4] > conf_thres
          ]  # confidence 根据obj confidence虑除背景目标
          x = x[
              ((x[:, 2:4] > min_wh) & (x[:, 2:4] < max_wh)).all(1)
          ]  # width-height 虑除小目标
  
          # If none remain process next image
          if not x.shape[0]:
              continue
  
          # Compute conf
          x[..., 5:] *= x[..., 4:5]  # conf = obj_conf * cls_conf
  
          # Box (center x, center y, width, height) to (x1, y1, x2, y2)
          box = xywh2xyxy(x[:, :4])
  
          # Detections matrix nx6 (xyxy, conf, cls)
          if multi_label:  # 针对每个类别执行非极大值抑制
              i, j = (x[:, 5:] > conf_thres).nonzero(as_tuple=False).t()
              x = torch.cat(
                  (
                      box[i],
                      x[i, j + 5].unsqueeze(1),
                      j.float().unsqueeze(1),
                  ),
                  1,
              )
          else:  # best class only  直接针对每个类别中概率最大的类别进行非极大值抑制处理
              conf, j = x[:, 5:].max(1)
              x = torch.cat(
                  (box, conf.unsqueeze(1), j.float().unsqueeze(1)), 1
              )[conf > conf_thres]
  
          # Filter by class
          if classes:
              x = x[
                  (
                      j.view(-1, 1)
                      == torch.tensor(classes, device=j.device)
                  ).any(1)
              ]
  
          # Apply finite constraint
          # if not torch.isfinite(x).all():
          #     x = x[torch.isfinite(x).all(1)]
  
          # If none remain process next image
          n = x.shape[0]  # number of boxes
          if not n:
              continue
  
          # Sort by confidence
          # x = x[x[:, 4].argsort(descending=True)]
  
          # Batched NMS
          c = x[:, 5] * 0 if agnostic else x[:, 5]  # classes
          boxes, scores = (
              x[:, :4].clone() + c.view(-1, 1) * max_wh,
              x[:, 4],
          )  # boxes (offset by class), scores
          i = torchvision.ops.nms(boxes, scores, iou_thres)
          i = i[:max_num]  # 最多只保留前max_num个目标信息
          if merge and (
              1 < n < 3e3
          ):  # Merge NMS (boxes merged using weighted mean)
              try:  # update boxes as boxes(i,4) = weights(i,n) * boxes(n,4)
                  iou = (
                      box_iou(boxes[i], boxes) > iou_thres
                  )  # iou matrix
                  weights = iou * scores[None]  # box weights
                  x[i, :4] = torch.mm(
                      weights, x[:, :4]
                  ).float() / weights.sum(
                      1, keepdim=True
                  )  # merged boxes
                  # i = i[iou.sum(1) > 1]  # require redundancy
              except:  # possible CUDA error https://github.com/ultralytics/yolov3/issues/1139
                  print(x, i, x.shape, i.shape)
                  pass
  
          output[xi] = x[i]
          if (time.time() - t) > time_limit:
              break  # time limit exceeded
  
      return output
  
imports: import glob
  import math
  import os
  import random
  import time
  import cv2
  import matplotlib
  import numpy
  import torch
  import torch.nn
  import torchvision
  from tqdm import tqdm
  from build_utils import torch_utils
label_desc: Use image node_id 13 for calling a global function with example usage: non_max_suppression(prediction, conf_thres, iou_thres, multi_label, classes, agnostic, max_num) and returns: output