class_docstr: BoxIOU.
docstr: Generic functions to compute precision/recall for object detection.
docstr_tok: ["Generic","functions","to","compute","precision\/recall","for","object","detection","."]
code: def _eval_detections_per_class(self, pred, gt, ovthresh=0.25):
      """Generic functions to compute precision/recall for object detection."""
  
      # construct gt objects
      class_recs = (
          {}
      )  # {img_id: {'bbox': bbox list, 'det': matched list}}
      npos = 0
      for img_id in gt.keys():
          bbox = np.array(gt[img_id])
          det = [False] * len(bbox)
          npos += len(bbox)
          class_recs[img_id] = {"bbox": bbox, "det": det}
      # pad empty list to all other imgids
      for img_id in pred:
          if img_id not in gt:
              class_recs[img_id] = {"bbox": np.array([]), "det": []}
  
      # construct dets
      image_ids = []
      confidence = []
      bb = []
      for img_id in pred:
          for box, score in pred[img_id]:
              image_ids.append(img_id)
              confidence.append(score)
              bb.append(box)
      confidence = np.array(confidence)
      bb = np.array(bb)  # (nd,4 or 8,3 or 6)
  
      # sort by confidence
      sorted_ind = np.argsort(-confidence)
      bb = bb[sorted_ind, ...]
      image_ids = [image_ids[x] for x in sorted_ind]
  
      # go down dets and mark TPs and FPs
      nd = len(image_ids)
      tp = np.zeros(nd)
      fp = np.zeros(nd)
      for d in range(nd):
          r = class_recs[image_ids[d]]
          bb = bb[d, ...].astype(float)
          ovmax = -np.inf
          bbgt = r["bbox"].astype(float)
  
          if bbgt.size > 0:
              # compute overlaps
              for j in range(bbgt.shape[0]):
                  iou = self._get_iou_main(
                      self.get_iou_func, (bb, bbgt[j, ...])
                  )
                  if iou > ovmax:
                      ovmax = iou
                      jmax = j
  
          if ovmax > ovthresh:
              if not r["det"][jmax]:
                  tp[d] = 1.0
                  r["det"][jmax] = 1
              else:
                  fp[d] = 1.0
          else:
              fp[d] = 1.0
  
      # compute precision recall
      fp = np.cumsum(fp)
      tp = np.cumsum(tp)
      rec = tp / float(npos + 1e-5)
      # avoid divide by zero in case the first detection matches a difficult
      # ground truth
      prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps)
      ap = self._voc_ap(rec, prec)
  
      return rec, prec, ap
  
imports: import os
  import pickle
  from absl import logging
  import matplotlib.pyplot
  import numpy
  import tensorflow
  from tensorflow_graphics.geometry.representation import grid
  from tensorflow_graphics.math.interpolation import trilinear
  from tensorflow_graphics.projects.points_to_3Dobjects.models import centernet_utils
  from tensorflow_graphics.projects.points_to_3Dobjects.utils import tf_utils
  from google3.pyglib import gfile
  from google3.third_party.google_research.google_research.tf3d.object_detection.box_utils import np_box_ops
label_desc: Use image node_id 6 for calling the BoxIoUMetric obj's underlying member method code with example usage: obj._eval_detections_per_class(pred, gt, ovthresh) and returns: rec,  prec,  ap