code: def _compute_matches(
      cats, pred_ious, iou_thresh, iscrowd, eval_key, id_key, iou_key
  ):
      matches = []
  
      # 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
                  for gt_id, iou in pred_ious[pred.id]:
                      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:
                          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 iou < best_match_iou:
                          continue
  
                      best_match_iou = iou
                      best_match = gt_id
  
                  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:
                          gt[eval_key] = (
                              "tp" if gt.label == pred.label else "fn"
                          )
                          gt[id_key] = pred.id
                          gt[iou_key] = best_match_iou
  
                      pred[eval_key] = (
                          "tp" if gt.label == pred.label else "fp"
                      )
                      pred[id_key] = best_match
                      pred[iou_key] = best_match_iou
  
                      matches.append(
                          (
                              gt.label,
                              pred.label,
                              best_match_iou,
                              pred.confidence,
                              gt.id,
                              pred.id,
                              iscrowd(gt),
                          )
                      )
                  else:
                      pred[eval_key] = "fp"
                      matches.append(
                          (
                              None,
                              pred.label,
                              None,
                              pred.confidence,
                              None,
                              pred.id,
                              None,
                          )
                      )
  
              elif pred.label == cat:
                  pred[eval_key] = "fp"
                  matches.append(
                      (
                          None,
                          pred.label,
                          None,
                          pred.confidence,
                          None,
                          pred.id,
                          None,
                      )
                  )
  
          # 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,
                          iscrowd(gt),
                      )
                  )
  
      return matches
  
imports: import logging
  from collections import defaultdict
  import numpy
  import eta.core.utils
  import fiftyone.core.plots
  import fiftyone.utils.iou
  from .detection import DetectionEvaluation, DetectionEvaluationConfig, DetectionResults
label_desc: Use image node_id 4 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