code: def _compute_matches(
      cats, pred_ious, iou_thresh, iscrowd, eval_key, id_key, iou_key
  ):
      matches = []
  
      # For efficient rounding
      p_round = 10**10
  
      # Match preds to GT, highest confidence first
      for cat, objects in cats.items():
          gt_map = {gt.id: gt for gt in objects["gts"]}
  
          # Match each prediction to the highest available IoU ground truth
          for pred in objects["preds"]:
              if pred.id in pred_ious:
                  best_match = None
                  best_match_iou = iou_thresh
                  highest_already_matched_iou = iou_thresh
                  for gt_id, iou in pred_ious[pred.id]:
                      iou = int(iou * p_round + 0.5) / p_round
                      gt = gt_map[gt_id]
                      gt_iscrowd = iscrowd(gt)
  
                      # Only iscrowd GTs can have multiple matches
                      if gt[id_key] != _NO_MATCH_ID and not gt_iscrowd:
                          if iou > highest_already_matched_iou:
                              highest_already_matched_iou = iou
                              if iou > best_match_iou:
                                  best_match = None
                                  best_match_iou = iou_thresh
  
                          continue
  
                      # If matching classwise=False
                      # Only objects with the same class can match a crowd
                      if gt_iscrowd and gt.label != pred.label:
                          continue
  
                      # Crowds are last in order of GTs
                      # If we already matched a non-crowd and are on a crowd,
                      # then break
                      if (
                          best_match
                          and not iscrowd(gt_map[best_match])
                          and gt_iscrowd
                      ):
                          break
  
                      # If you already perfectly matched a GT
                      # then there is no reason to continue looking
                      # if you match multiple crowds with iou=1, choose the first
                      if best_match_iou == 1:
                          break
  
                      if iou < best_match_iou:
                          continue
  
                      best_match_iou = iou
                      best_match = gt_id
  
                  if highest_already_matched_iou > best_match_iou:
                      if best_match is not None and not iscrowd(
                          gt_map[best_match]
                      ):
                          # Note: This differs from COCO in that Open Images
                          # objects are only matched with the highest IoU GT or a
                          # crowd. An object will not be matched with a secondary
                          # highest IoU GT if the highest IoU GT was already
                          # matched with a different object
  
                          best_match = None
  
                  if best_match:
                      gt = gt_map[best_match]
  
                      # For crowd GTs, record info for first (highest confidence)
                      # matching prediction on the GT object
                      if gt[id_key] == _NO_MATCH_ID:
                          record_match = True
  
                          gt[eval_key] = (
                              "tp" if gt.label == pred.label else "fn"
                          )
                          gt[id_key] = pred.id
                          gt[iou_key] = best_match_iou
                      else:
                          # In Open Images-style evaluation, only the first match
                          # for a crowd GT is recorded in `matches`
                          record_match = False
  
                      pred[eval_key] = (
                          "tp" if gt.label == pred.label else "fp"
                      )
                      pred[id_key] = best_match
                      pred[iou_key] = best_match_iou
  
                      if record_match:
                          matches.append(
                              (
                                  gt.label,
                                  pred.label,
                                  best_match_iou,
                                  pred.confidence,
                                  gt.id,
                                  pred.id,
                              )
                          )
                  else:
                      pred[eval_key] = "fp"
                      matches.append(
                          (
                              None,
                              pred.label,
                              None,
                              pred.confidence,
                              None,
                              pred.id,
                          )
                      )
              elif pred.label == cat:
                  pred[eval_key] = "fp"
                  matches.append(
                      (
                          None,
                          pred.label,
                          None,
                          pred.confidence,
                          None,
                          pred.id,
                      )
                  )
  
          # Leftover GTs are false negatives
          for gt in objects["gts"]:
              if gt[id_key] == _NO_MATCH_ID:
                  gt[eval_key] = "fn"
                  matches.append(
                      (gt.label, None, None, None, gt.id, None)
                  )
  
      return matches
  
imports: from collections import defaultdict
  from copy import deepcopy
  import numpy
  import fiftyone.core.plots
  import fiftyone.utils.iou
  from .detection import DetectionEvaluation, DetectionEvaluationConfig, DetectionResults
label_desc: Use image node_id 5 for calling a global function with example usage: _compute_matches(cats, pred_ious, iou_thresh, iscrowd, eval_key, id_key, iou_key) and returns: matches