in downstream/votenet/datasets/evaluation/evaluate_object_detection_helper.py [0:0]
def eval_det_cls(pred, gt, ovthresh=0.25, use_07_metric=False, get_iou_func=get_iou):
""" Generic functions to compute precision/recall for object detection
for a single class.
Input:
pred: map of {img_id: [(bbox, score)]} where bbox is numpy array of size 6
gt: map of {img_id: [bbox]}
ovthresh: scalar, iou threshold
use_07_metric: bool, if True use VOC07 11 point method
Output:
rec: numpy array of length nd
prec: numpy array of length nd
ap: scalar, average precision
"""
# 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]) # bbox: (n,6). n: number of bounding box in an img_id. 6 value is 3 value of center and 3 value of length
det = [False] * len(bbox) # length = n
npos += len(bbox) # sum of GT bounding boxes in all scenes
class_recs[img_id] = {'bbox': bbox, 'det': det}
# pad empty list to all other imgids
for img_id in pred.keys():
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.keys():
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) # sort in descending order. Meaning: largest confidence first
sorted_scores = np.sort(-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) #nd: number of bounding boxes in all scenes
tp = np.zeros(nd)
fp = np.zeros(nd)
for d in range(nd):
#if d%100==0: print(d)
R = class_recs[image_ids[d]] # all GT BB in a scene according to the level of confidence
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 = get_iou_main(get_iou_func, (bb, BBGT[j,...]))
if iou > ovmax:
ovmax = iou # ovmax is the largest iou between BB and all ground truth boxes in BBGT
jmax = j
#print d, ovmax
if ovmax > ovthresh:
if not R['det'][jmax]:
tp[d] = 1.# if this BB have IoU > 0.25 with a GT box in BBGT, and this GTbox still not has any BB assigned to it, then this BB is TP
R['det'][jmax] = 1
else:
fp[d] = 1. #else, if this BB have IoU > 0.25 with a GT box in BBGT, and this GTbox already has a BB1 assigned to it (meaning that BB1 has higher confidence than this BB), then this BB is FP
else:
fp[d] = 1.#if this BB does not have IoU>0.25 with any GT boxes in BBGT, then it is FP
# compute precision recall
fp = np.cumsum(fp)
tp = np.cumsum(tp)
rec = tp / float(npos)
#print('NPOS: ', npos)
# 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 = voc_ap(rec, prec, use_07_metric)
return rec, prec, ap