def fused_compute_statistics( overlaps, pr, gt_nums, dt_nums, dc_nums, gt_datas, dt_datas, dontcares, ignored_gts, ignored_dets, metric, min_overlap, thresholds, compute_aos=False, ): gt_num = 0 dt_num = 0 dc_num = 0 for i in range(gt_nums.shape[0]): for t, thresh in enumerate(thresholds): overlap = overlaps[ dt_num : dt_num + dt_nums[i], gt_num : gt_num + gt_nums[i] ] gt_data = gt_datas[gt_num : gt_num + gt_nums[i]] dt_data = dt_datas[dt_num : dt_num + dt_nums[i]] ignored_gt = ignored_gts[gt_num : gt_num + gt_nums[i]] ignored_det = ignored_dets[dt_num : dt_num + dt_nums[i]] dontcare = dontcares[dc_num : dc_num + dc_nums[i]] tp, fp, fn, similarity, _ = compute_statistics_jit( overlap, gt_data, dt_data, ignored_gt, ignored_det, dontcare, metric, min_overlap=min_overlap, thresh=thresh, compute_fp=True, compute_aos=compute_aos, ) pr[t, 0] += tp pr[t, 1] += fp pr[t, 2] += fn if similarity != -1: pr[t, 3] += similarity gt_num += gt_nums[i] dt_num += dt_nums[i] dc_num += dc_nums[i]
def eval_class_v3( gt_annos, dt_annos, current_classes, difficultys, metric, min_overlaps, compute_aos=False, z_axis=1, z_center=1.0, num_parts=50, ): """Kitti eval. support 2d/bev/3d/aos eval. support 0.5:0.05:0.95 coco AP. Args: gt_annos: dict, must from get_label_annos() in kitti_common.py dt_annos: dict, must from get_label_annos() in kitti_common.py current_class: int, 0: car, 1: pedestrian, 2: cyclist difficulty: int. eval difficulty, 0: easy, 1: normal, 2: hard metric: eval type. 0: bbox, 1: bev, 2: 3d min_overlap: float, min overlap. official: [[0.7, 0.5, 0.5], [0.7, 0.5, 0.5], [0.7, 0.5, 0.5]] format: [metric, class]. choose one from matrix above. num_parts: int. a parameter for fast calculate algorithm Returns: dict of recall, precision and aos """ assert len(gt_annos) == len(dt_annos) num_examples = len(gt_annos) split_parts = get_split_parts(num_examples, num_parts) split_parts = [i for i in split_parts if i != 0] rets = calculate_iou_partly(dt_annos, gt_annos, metric, num_parts, z_axis=z_axis, z_center=z_center) overlaps, parted_overlaps, total_dt_num, total_gt_num = rets N_SAMPLE_PTS = 41 num_minoverlap = len(min_overlaps) num_class = len(current_classes) num_difficulty = len(difficultys) precision = np.zeros( [num_class, num_difficulty, num_minoverlap, N_SAMPLE_PTS]) recall = np.zeros( [num_class, num_difficulty, num_minoverlap, N_SAMPLE_PTS]) aos = np.zeros([num_class, num_difficulty, num_minoverlap, N_SAMPLE_PTS]) all_thresholds = np.zeros( [num_class, num_difficulty, num_minoverlap, N_SAMPLE_PTS]) for m, current_class in enumerate(current_classes): for l, difficulty in enumerate(difficultys): rets = prepare_data( gt_annos, dt_annos, current_class, difficulty=difficulty, clean_data=clean_data, ) ( gt_datas_list, dt_datas_list, ignored_gts, ignored_dets, dontcares, total_dc_num, total_num_valid_gt, ) = rets for k, min_overlap in enumerate(min_overlaps[:, metric, m]): thresholdss = [] for i in range(len(gt_annos)): rets = compute_statistics_jit( overlaps[i], gt_datas_list[i], dt_datas_list[i], ignored_gts[i], ignored_dets[i], dontcares[i], metric, min_overlap=min_overlap, thresh=0.0, compute_fp=False, ) tp, fp, fn, similarity, thresholds = rets thresholdss += thresholds.tolist() thresholdss = np.array(thresholdss) thresholds = get_thresholds(thresholdss, total_num_valid_gt) thresholds = np.array(thresholds) # print(thresholds) all_thresholds[m, l, k, :len(thresholds)] = thresholds pr = np.zeros([len(thresholds), 4]) idx = 0 for j, num_part in enumerate(split_parts): gt_datas_part = np.concatenate( gt_datas_list[idx:idx + num_part], 0) dt_datas_part = np.concatenate( dt_datas_list[idx:idx + num_part], 0) dc_datas_part = np.concatenate( dontcares[idx:idx + num_part], 0) ignored_dets_part = np.concatenate( ignored_dets[idx:idx + num_part], 0) ignored_gts_part = np.concatenate( ignored_gts[idx:idx + num_part], 0) fused_compute_statistics( parted_overlaps[j], pr, total_gt_num[idx:idx + num_part], total_dt_num[idx:idx + num_part], total_dc_num[idx:idx + num_part], gt_datas_part, dt_datas_part, dc_datas_part, ignored_gts_part, ignored_dets_part, metric, min_overlap=min_overlap, thresholds=thresholds, compute_aos=compute_aos, ) idx += num_part for i in range(len(thresholds)): # recall[m, l, k, i] = pr[i, 0] / (pr[i, 0] + pr[i, 2]) precision[m, l, k, i] = pr[i, 0] / (pr[i, 0] + pr[i, 1]) if compute_aos: aos[m, l, k, i] = pr[i, 3] / (pr[i, 0] + pr[i, 1]) for i in range(len(thresholds)): precision[m, l, k, i] = np.max(precision[m, l, k, i:], axis=-1) if compute_aos: aos[m, l, k, i] = np.max(aos[m, l, k, i:], axis=-1) # use interp to calculate recall """ current_recalls = np.linspace(0, 1, 41) prec_unique, inds = np.unique(precision[m, l, k], return_index=True) current_recalls = current_recalls[inds] f = interp1d(prec_unique, current_recalls) precs_for_recall = np.linspace(0, 1, 41) max_prec = np.max(precision[m, l, k]) valid_prec = precs_for_recall < max_prec num_valid_prec = valid_prec.sum() recall[m, l, k, :num_valid_prec] = f(precs_for_recall[valid_prec]) """ ret_dict = { "recall": recall, # [num_class, num_difficulty, num_minoverlap, N_SAMPLE_PTS] "precision": precision, "orientation": aos, "thresholds": all_thresholds, "min_overlaps": min_overlaps, } return ret_dict