code: def _compute_bbox_ious(preds, gts, iscrowd=None, classwise=False):
      is_symmetric = preds is gts
  
      if iscrowd is not None:
          gt_crowds = [iscrowd(gt) for gt in gts]
      else:
          gt_crowds = [False] * len(gts)
  
      if isinstance(preds[0], fol.Polyline):
          preds = _polylines_to_detections(preds)
  
          if is_symmetric:
              gts = preds
          else:
              gts = _polylines_to_detections(gts)
  
      if _get_bbox_dim(gts[0]) == 3:
          bbox_iou_fcn = _compute_cuboid_iou
      else:
          bbox_iou_fcn = _compute_bbox_iou
  
      ious = np.zeros((len(preds), len(gts)))
  
      for j, (gt, gt_crowd) in enumerate(zip(gts, gt_crowds)):
          for i, pred in enumerate(preds):
              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:
                  iou = bbox_iou_fcn(gt, pred, gt_crowd=gt_crowd)
  
              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 13 for calling a global function with example usage: _compute_bbox_ious(preds, gts, iscrowd, classwise) and returns: ious