in tools/kitti_eval/evaluate_object_3d_offline_ap11.cpp [622:704]
bool eval_class (FILE *fp_det, FILE *fp_ori, CLASSES current_class,
const vector< vector<tGroundtruth> > &groundtruth,
const vector< vector<tDetection> > &detections, bool compute_aos,
double (*boxoverlap)(tDetection, tGroundtruth, int32_t),
vector<double> &precision, vector<double> &aos,
DIFFICULTY difficulty, METRIC metric) {
assert(groundtruth.size() == detections.size());
// init
int32_t n_gt=0; // total no. of gt (denominator of recall)
vector<double> v, thresholds; // detection scores, evaluated for recall discretization
vector< vector<int32_t> > ignored_gt, ignored_det; // index of ignored gt detection for current class/difficulty
vector< vector<tGroundtruth> > dontcare; // index of dontcare areas, included in ground truth
// for all test images do
for (int32_t i=0; i<groundtruth.size(); i++){
// holds ignored ground truth, ignored detections and dontcare areas for current frame
vector<int32_t> i_gt, i_det;
vector<tGroundtruth> dc;
// only evaluate objects of current class and ignore occluded, truncated objects
cleanData(current_class, groundtruth[i], detections[i], i_gt, dc, i_det, n_gt, difficulty);
ignored_gt.push_back(i_gt);
ignored_det.push_back(i_det);
dontcare.push_back(dc);
// compute statistics to get recall values
tPrData pr_tmp = tPrData();
pr_tmp = computeStatistics(current_class, groundtruth[i], detections[i], dc, i_gt, i_det, false, boxoverlap, metric);
// add detection scores to vector over all images
for(int32_t j=0; j<pr_tmp.v.size(); j++)
v.push_back(pr_tmp.v[j]);
}
// get scores that must be evaluated for recall discretization
thresholds = getThresholds(v, n_gt);
// compute TP,FP,FN for relevant scores
vector<tPrData> pr;
pr.assign(thresholds.size(),tPrData());
for (int32_t i=0; i<groundtruth.size(); i++){
// for all scores/recall thresholds do:
for(int32_t t=0; t<thresholds.size(); t++){
tPrData tmp = tPrData();
tmp = computeStatistics(current_class, groundtruth[i], detections[i], dontcare[i],
ignored_gt[i], ignored_det[i], true, boxoverlap, metric,
compute_aos, thresholds[t], t==38);
// add no. of TP, FP, FN, AOS for current frame to total evaluation for current threshold
pr[t].tp += tmp.tp;
pr[t].fp += tmp.fp;
pr[t].fn += tmp.fn;
if(tmp.similarity!=-1)
pr[t].similarity += tmp.similarity;
}
}
// compute recall, precision and AOS
vector<double> recall;
precision.assign(N_SAMPLE_PTS, 0);
if(compute_aos)
aos.assign(N_SAMPLE_PTS, 0);
double r=0;
for (int32_t i=0; i<thresholds.size(); i++){
r = pr[i].tp/(double)(pr[i].tp + pr[i].fn);
recall.push_back(r);
precision[i] = pr[i].tp/(double)(pr[i].tp + pr[i].fp);
if(compute_aos)
aos[i] = pr[i].similarity/(double)(pr[i].tp + pr[i].fp);
}
// filter precision and AOS using max_{i..end}(precision)
for (int32_t i=0; i<thresholds.size(); i++){
precision[i] = *max_element(precision.begin()+i, precision.end());
if(compute_aos)
aos[i] = *max_element(aos.begin()+i, aos.end());
}
// save statisics and finish with success
saveStats(precision, aos, fp_det, fp_ori);
return true;
}