def non_max_suppression(boxlist, thresh, max_output_size, scope=None):
  """Non maximum suppression.

  This op greedily selects a subset of detection bounding boxes, pruning
  away boxes that have high IOU (intersection over union) overlap (> thresh)
  with already selected boxes.  Note that this only works for a single class ---
  to apply NMS to multi-class predictions, use MultiClassNonMaxSuppression.

  Args:
    boxlist: BoxList holding N boxes.  Must contain a 'scores' field
      representing detection scores.
    thresh: scalar threshold
    max_output_size: maximum number of retained boxes
    scope: name scope.

  Returns:
    a BoxList holding M boxes where M <= max_output_size
  Raises:
    ValueError: if thresh is not in [0, 1]
  """
  with tf.name_scope(scope, 'NonMaxSuppression'):
    if not 0 <= thresh <= 1.0:
      raise ValueError('thresh must be between 0 and 1')
    if not isinstance(boxlist, box_list.BoxList):
      raise ValueError('boxlist must be a BoxList')
    if not boxlist.has_field('scores'):
      raise ValueError('input boxlist must have \'scores\' field')
    selected_indices = tf.image.non_max_suppression(
        boxlist.get(), boxlist.get_field('scores'),
        max_output_size, iou_threshold=thresh)
    return gather(boxlist, selected_indices)
Non maximum suppression.

  This op greedily selects a subset of detection bounding boxes, pruning
  away boxes that have high IOU (intersection over union) overlap (> thresh)
  with already selected boxes.  Note that this only works for a single class ---
  to apply NMS to multi-class predictions, use MultiClassNonMaxSuppression.

  Args:
    boxlist: BoxList holding N boxes.  Must contain a 'scores' field
      representing detection scores.
    thresh: scalar threshold
    max_output_size: maximum number of retained boxes
    scope: name scope.

  Returns:
    a BoxList holding M boxes where M <= max_output_size
  Raises:
    ValueError: if thresh is not in [0, 1]
  
inference_api/src/main/object_detection/core/box_list_ops.py