code: def ap_per_class(tp, conf, pred_cls, target_cls):
      """Compute the average precision, given the recall and precision curves.
      Source: https://github.com/rafaelpadilla/Object-Detection-Metrics.
      # Arguments
          tp:  True positives (nparray, nx1 or nx10).
          conf:  Objectness value from 0-1 (nparray).
          pred_cls:  Predicted object classes (nparray).
          target_cls:  True object classes (nparray).
      # Returns
          The average precision as computed in py-faster-rcnn.
      """
  
      # Sort by objectness
      i = np.argsort(-conf)
      tp, conf, pred_cls = tp[i], conf[i], pred_cls[i]
  
      # Find unique classes
      unique_classes = np.unique(target_cls)
      nc = unique_classes.shape[
          0
      ]  # number of classes, number of detections
  
      # Create Precision-Recall curve and compute AP for each class
      px = np.linspace(0, 1, 1000)
      ap, p, r = (
          np.zeros((nc, tp.shape[1])),
          np.zeros((nc, 1000)),
          np.zeros((nc, 1000)),
      )
      for ci, c in enumerate(unique_classes):
          i = pred_cls == c
          n_l = (target_cls == c).sum()  # number of labels
          n_p = i.sum()  # number of predictions
  
          if n_p == 0 or n_l == 0:
              continue
          else:
              # Accumulate FPs and TPs
              fpc = (1 - tp[i]).cumsum(0)
              tpc = tp[i].cumsum(0)
  
              # Recall
              recall = tpc / (n_l + 1e-16)  # recall curve
              r[ci] = np.interp(
                  -px, -conf[i], recall[:, 0], left=0
              )  # negative x, xp because xp decreases
  
              # Precision
              precision = tpc / (tpc + fpc)  # precision curve
              p[ci] = np.interp(
                  -px, -conf[i], precision[:, 0], left=1
              )  # p at pr_score
  
              # AP from recall-precision curve
              for j in range(tp.shape[1]):
                  ap[ci, j], mpre, mrec = compute_ap(
                      recall[:, j], precision[:, j]
                  )
  
      # Compute F1 (harmonic mean of precision and recall)
      f1 = 2 * p * r / (p + r + 1e-16)
      i = f1.mean(0).argmax()  # max F1 index
  
      return (
          p[:, i],
          r[:, i],
          ap,
          f1[:, i],
          unique_classes.astype("int32"),
      )
  
imports: import math
  import warnings
  import numpy
  import torch
label_desc: Use image node_id 1 for calling a global function with example usage: ap_per_class(tp, conf, pred_cls, target_cls) and returns: p,  r,  ap,  f1,  unique_classes