code: def _compute_polygon_ious(
      preds,
      gts,
      error_level,
      iscrowd=None,
      classwise=False,
      gt_crowds=None,
  ):
      is_symmetric = preds is gts
  
      with contextlib.ExitStack() as context:
          # We're ignoring errors, so suppress shapely logging that occurs when
          # invalid geometries are encountered
          if error_level > 1:
              # pylint: disable=no-member
              context.enter_context(
                  fou.LoggingLevel(logging.CRITICAL, logger="shapely")
              )
  
          num_pred = len(preds)
          pred_polys = _polylines_to_shapely(preds, error_level)
          pred_labels = [pred.label for pred in preds]
          pred_areas = [pred_poly.area for pred_poly in pred_polys]
  
          if is_symmetric:
              num_gt = num_pred
              gt_polys = pred_polys
              gt_labels = pred_labels
              gt_areas = pred_areas
          else:
              num_gt = len(gts)
              gt_polys = _polylines_to_shapely(gts, error_level)
              gt_labels = [gt.label for gt in gts]
              gt_areas = [gt_poly.area for gt_poly in gt_polys]
  
          if iscrowd is not None:
              gt_crowds = [iscrowd(gt) for gt in gts]
          elif gt_crowds is None:
              gt_crowds = [False] * num_gt
  
          ious = np.zeros((num_pred, num_gt))
  
          for j, (gt_poly, gt_label, gt_area, gt_crowd) in enumerate(
              zip(gt_polys, gt_labels, gt_areas, gt_crowds)
          ):
              for i, (pred_poly, pred_label, pred_area) in enumerate(
                  zip(pred_polys, pred_labels, pred_areas)
              ):
                  if is_symmetric and i < j:
                      iou = ious[j, i]
                  elif is_symmetric and i == j:
                      iou = 1
                  elif classwise and pred_label != gt_label:
                      continue
                  else:
                      try:
                          inter = gt_poly.intersection(pred_poly).area
                      except Exception as e:
                          inter = 0.0
                          fou.handle_error(
                              ValueError(
                                  "Failed to compute intersection of predicted "
                                  "object '%s' and ground truth object '%s'"
                                  % (preds[i].id, gts[j].id)
                              ),
                              error_level,
                              base_error=e,
                          )
  
                      if gt_crowd:
                          union = pred_area
                      else:
                          union = pred_area + gt_area - inter
  
                      iou = min(etan.safe_divide(inter, union), 1)
  
                  ious[i, j] = iou
  
      return ious
  
imports: import contextlib
  import itertools
  import logging
  import numpy
  import scipy.spatial
  import eta.core.numutils
  import eta.core.utils
  import fiftyone.core.labels
  import fiftyone.core.utils
  import fiftyone.core.validation
  from .utils3d import compute_cuboid_iou
label_desc: Use image node_id 14 for calling a global function with example usage: _compute_polygon_ious(preds, gts, error_level, iscrowd, classwise, gt_crowds) and returns: ious