code: def tpfp_default(
      det_bboxes,
      gt_bboxes,
      gt_bboxes_ignore=None,
      iou_thr=0.5,
      area_ranges=None,
  ):
      """Check if detected bboxes are true positive or false positive.
  
      Args:
          det_bbox (ndarray): Detected bboxes of this image, of shape (m, 5).
          gt_bboxes (ndarray): GT bboxes of this image, of shape (n, 4).
          gt_bboxes_ignore (ndarray): Ignored gt bboxes of this image,
              of shape (k, 4). Default: None
          iou_thr (float): IoU threshold to be considered as matched.
              Default: 0.5.
          area_ranges (list[tuple] | None): Range of bbox areas to be evaluated,
              in the format [(min1, max1), (min2, max2), ...]. Default: None.
  
      Returns:
          tuple[np.ndarray]: (tp, fp) whose elements are 0 and 1. The shape of
              each array is (num_scales, m).
      """
      # an indicator of ignored gts
      gt_ignore_inds = np.concatenate(
          (
              np.zeros(gt_bboxes.shape[0], dtype=np.bool),
              np.ones(gt_bboxes_ignore.shape[0], dtype=np.bool),
          )
      )
      # stack gt_bboxes and gt_bboxes_ignore for convenience
      gt_bboxes = np.vstack((gt_bboxes, gt_bboxes_ignore))
  
      num_dets = det_bboxes.shape[0]
      num_gts = gt_bboxes.shape[0]
      if area_ranges is None:
          area_ranges = [(None, None)]
      num_scales = len(area_ranges)
      # tp and fp are of shape (num_scales, num_gts), each row is tp or fp of
      # a certain scale
      tp = np.zeros((num_scales, num_dets), dtype=np.float32)
      fp = np.zeros((num_scales, num_dets), dtype=np.float32)
  
      # if there is no gt bboxes in this image, then all det bboxes
      # within area range are false positives
      if gt_bboxes.shape[0] == 0:
          if area_ranges == [(None, None)]:
              fp[...] = 1
          else:
              det_areas = (det_bboxes[:, 2] - det_bboxes[:, 0]) * (
                  det_bboxes[:, 3] - det_bboxes[:, 1]
              )
              for i, (min_area, max_area) in enumerate(area_ranges):
                  fp[
                      i,
                      (det_areas >= min_area) & (det_areas < max_area),
                  ] = 1
          return tp, fp
  
      ious = bbox_overlaps(det_bboxes, gt_bboxes)
      # for each det, the max iou with all gts
      ious_max = ious.max(axis=1)
      # for each det, which gt overlaps most with it
      ious_argmax = ious.argmax(axis=1)
      # sort all dets in descending order by scores
      sort_inds = np.argsort(-det_bboxes[:, -1])
      for k, (min_area, max_area) in enumerate(area_ranges):
          gt_covered = np.zeros(num_gts, dtype=bool)
          # if no area range is specified, gt_area_ignore is all False
          if min_area is None:
              gt_area_ignore = np.zeros_like(gt_ignore_inds, dtype=bool)
          else:
              gt_areas = (gt_bboxes[:, 2] - gt_bboxes[:, 0]) * (
                  gt_bboxes[:, 3] - gt_bboxes[:, 1]
              )
              gt_area_ignore = (gt_areas < min_area) | (
                  gt_areas >= max_area
              )
          for i in sort_inds:
              if ious_max[i] >= iou_thr:
                  matched_gt = ious_argmax[i]
                  if not (
                      gt_ignore_inds[matched_gt]
                      or gt_area_ignore[matched_gt]
                  ):
                      if not gt_covered[matched_gt]:
                          gt_covered[matched_gt] = True
                          tp[k, i] = 1
                      else:
                          fp[k, i] = 1
                  # otherwise ignore this detected bbox, tp = 0, fp = 0
              elif min_area is None:
                  fp[k, i] = 1
              else:
                  bbox = det_bboxes[i, :4]
                  area = (bbox[2] - bbox[0]) * (bbox[3] - bbox[1])
                  if area >= min_area and area < max_area:
                      fp[k, i] = 1
      return tp, fp
  
file_path: insightface/detection/scrfd/mmdet/core/evaluation/mean_ap.py
imports: from multiprocessing import Pool
  import mmcv
  import numpy
  from mmcv.utils import print_log
  from terminaltables import AsciiTable
  from .bbox_overlaps import bbox_overlaps
  from .class_names import get_classes
label_desc: Use image node_id 3 for calling a global function with example usage: tpfp_default(det_bboxes, gt_bboxes, gt_bboxes_ignore, iou_thr, area_ranges) and returns: tp,  fp, tp,  fp