code: def filter_detections(
      boxes,
      classification,
      other=[],
      class_specific_filter=True,
      nms=True,
      score_threshold=0.05,
      max_detections=300,
      nms_threshold=0.5,
  ):
      """Filter detections using the boxes and classification values.
  
      Args
          boxes                 : Tensor of shape (num_boxes, 4) containing the boxes in (x1, y1, x2, y2) format.
          classification        : Tensor of shape (num_boxes, num_classes) containing the classification scores.
          other                 : List of tensors of shape (num_boxes, ...) to filter along with the boxes and classification scores.
          class_specific_filter : Whether to perform filtering per class, or take the best scoring class and filter those.
          nms                   : Flag to enable/disable non maximum suppression.
          score_threshold       : Threshold used to prefilter the boxes with.
          max_detections        : Maximum number of detections to keep.
          nms_threshold         : Threshold for the IoU value to determine when a box should be suppressed.
  
      Returns
          A list of [boxes, scores, labels, other[0], other[1], ...].
          boxes is shaped (max_detections, 4) and contains the (x1, y1, x2, y2) of the non-suppressed boxes.
          scores is shaped (max_detections,) and contains the scores of the predicted class.
          labels is shaped (max_detections,) and contains the predicted label.
          other[i] is shaped (max_detections, ...) and contains the filtered other[i] data.
          In case there are less than max_detections detections, the tensors are padded with -1's.
      """
  
      def _filter_detections(scores, labels):
          # threshold based on score
          indices = tensorflow.where(
              keras.backend.greater(scores, score_threshold)
          )
  
          if nms:
              filtered_boxes = tensorflow.gather_nd(boxes, indices)
              filtered_scores = keras.backend.gather(scores, indices)[
                  :, 0
              ]
  
              # perform NMS
              nms_indices = tensorflow.image.non_max_suppression(
                  filtered_boxes,
                  filtered_scores,
                  max_output_size=max_detections,
                  iou_threshold=nms_threshold,
              )
  
              # filter indices based on NMS
              indices = keras.backend.gather(indices, nms_indices)
  
          # add indices to list of all indices
          labels = tensorflow.gather_nd(labels, indices)
          indices = keras.backend.stack([indices[:, 0], labels], axis=1)
  
          return indices
  
      if class_specific_filter:
          all_indices = []
          # perform per class filtering
          for c in range(int(classification.shape[1])):
              scores = classification[:, c]
              labels = c * tensorflow.ones(
                  (keras.backend.shape(scores)[0],), dtype="int64"
              )
              all_indices.append(_filter_detections(scores, labels))
  
          # concatenate indices to single tensor
          indices = keras.backend.concatenate(all_indices, axis=0)
      else:
          scores = keras.backend.max(classification, axis=1)
          labels = keras.backend.argmax(classification, axis=1)
          indices = _filter_detections(scores, labels)
  
      # select top k
      scores = tensorflow.gather_nd(classification, indices)
      labels = indices[:, 1]
      scores, top_indices = tensorflow.nn.top_k(
          scores,
          k=keras.backend.minimum(
              max_detections, keras.backend.shape(scores)[0]
          ),
      )
  
      # filter input using the final set of indices
      indices = keras.backend.gather(indices[:, 0], top_indices)
      boxes = keras.backend.gather(boxes, indices)
      labels = keras.backend.gather(labels, top_indices)
      other_ = [keras.backend.gather(o, indices) for o in other]
  
      # zero pad the outputs
      pad_size = keras.backend.maximum(
          0, max_detections - keras.backend.shape(scores)[0]
      )
      boxes = tensorflow.pad(
          boxes, [[0, pad_size], [0, 0]], constant_values=-1
      )
      scores = tensorflow.pad(
          scores, [[0, pad_size]], constant_values=-1
      )
      labels = tensorflow.pad(
          labels, [[0, pad_size]], constant_values=-1
      )
      labels = keras.backend.cast(labels, "int32")
      other_ = [
          tensorflow.pad(
              o,
              [[0, pad_size]]
              + [[0, 0] for _ in range(1, len(o.shape))],
              constant_values=-1,
          )
          for o in other_
      ]
  
      # set shapes, since we know what they are
      boxes.set_shape([max_detections, 4])
      scores.set_shape([max_detections])
      labels.set_shape([max_detections])
      for o, s in zip(
          other_, [list(keras.backend.int_shape(o)) for o in other]
      ):
          o.set_shape([max_detections] + s[1:])
  
      return [boxes, scores, labels] + other_
  
file_path: ImageAI/imageai_tf_deprecated/Detection/keras_retinanet/layers/filter_detections.py
imports: import tensorflow
  from tensorflow import keras
  from ..None import backend
label_desc: Use image node_id 1 for calling a global function with example usage: filter_detections(boxes, classification, other, class_specific_filter, nms, score_threshold, max_detections, nms_threshold) and returns: unknown, indices