diff --git a/demo/demo/map.cpp b/demo/demo/map.cpp index 1ad62a5..e32c302 100644 --- a/demo/demo/map.cpp +++ b/demo/demo/map.cpp @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) FatalError("Wrong labels file path."); //read mAP parameters - readParams( config_filename, classes, map_points, map_levels, map_step, + tk::dnn::readmAPParams( config_filename, classes, map_points, map_levels, map_step, IoU_thresh, conf_thresh, verbose); std::ofstream times, memory; @@ -104,7 +104,7 @@ int main(int argc, char *argv[]) std::ifstream all_labels(labels_path); std::string l_filename; - std::vector images; + std::vector images; std::vector detected_bbox; std::cout<<"Reading groundtruth and generating detections"</ / / / - BoundingBox b; + tk::dnn::BoundingBox b; b.x = (d.x + d.w/2) / width; b.y = (d.y + d.h/2) / height; b.w = d.w / width; @@ -175,10 +175,10 @@ int main(int argc, char *argv[]) for(std::string line; std::getline(labels, line); ) { std::istringstream in(line); - BoundingBox b; + tk::dnn::BoundingBox b; in >> b.cl >> b.x >> b.y >> b.w >> b.h; b.prob = 1; - b.truth_flag = 1; + b.truthFlag = 1; f.gt.push_back(b); if(show)// draw rectangle for groundtruth @@ -206,11 +206,11 @@ int main(int argc, char *argv[]) //compute mAP - double AP = computeMapNIoULevels(images,classes,IoU_thresh,conf_thresh, map_points, map_step, map_levels, verbose, write_res_on_file, net); + double AP = tk::dnn::computeMapNIoULevels(images,classes,IoU_thresh,conf_thresh, map_points, map_step, map_levels, verbose, write_res_on_file, net); std::cout<<"mAP "< -#include -#include - -#include - -#include "tkdnn.h" - - -struct BoundingBox : public tk::dnn::box -{ - friend std::ostream& operator<<(std::ostream& os, const BoundingBox& bb); - int unique_truth_index = -1; - int truth_flag = 0; - float max_IoU = 0; - - void clear(); -}; - -std::ostream& operator<<(std::ostream& os, const BoundingBox& bb); -bool boxComparison (const BoundingBox& a,const BoundingBox& b) ; - -struct Frame -{ - std::string l_filename; - std::string i_filename; - std::vector gt; - std::vector det; - - void print() const; -}; - -struct PR -{ - double precision = 0; - double recall = 0; - int tp = 0, fp = 0, fn = 0; - - void print(); -}; - -float overlap(float x1, float w1, float x2, float w2); -float boxIntersection(const BoundingBox &a, const BoundingBox &b); -float boxUnion(const BoundingBox &a, const BoundingBox &b); -float boxIoU(const BoundingBox &a, const BoundingBox &b); - -void readParams(char* config_filename, int& classes, int& map_points, - int& map_levels, float& map_step, float& IoU_thresh, - float& conf_thresh, bool& verbose); - -double computeMap(std::vector &images,const int classes,const float IoU_thresh, const float conf_thresh=0.3, const int map_points=101, const bool verbose=false); -double computeMapNIoULevels(std::vector &images,const int classes,const float i_IoU_thresh=0.5, const float conf_thresh=0.3, const int map_points=101, const float map_step=0.05, const int map_levels=10, const bool verbose=false, const bool write_on_file = false, std::string net = ""); - -void computeTPFPFN(std::vector &images,const int classes,const float IoU_thresh=0.5, const float conf_thresh=0.3, bool verbose=false, const bool write_on_file=false, std::string net=""); - -#endif /*EVALUATION_H*/ diff --git a/src/evaluation.cpp b/src/evaluation.cpp index 80b2e61..b41d88d 100644 --- a/src/evaluation.cpp +++ b/src/evaluation.cpp @@ -1,12 +1,13 @@ #include "evaluation.h" #include +namespace tk { namespace dnn { void BoundingBox::clear() { - unique_truth_index = -1; - truth_flag = 0; - max_IoU = 0; + uniqueTruthIndex = -1; + truthFlag = 0; + maxIoU = 0; } bool boxComparison (const BoundingBox& a,const BoundingBox& b) @@ -18,15 +19,15 @@ std::ostream& operator<<(std::ostream& os, const BoundingBox& bb) { os <<"w: "<< bb.w << ", h: "<< bb.h << ", x: "<< bb.x << ", y: "<< bb.y << ", cat: "<< bb.cl << ", conf: "<< bb.prob<< ", truth: "<< - bb.truth_flag<< ", assignedGT: "<< bb.unique_truth_index<< - ", maxIoU: "<< bb.max_IoU<<"\n"; + bb.truthFlag<< ", assignedGT: "<< bb.uniqueTruthIndex<< + ", maxIoU: "<< bb.maxIoU<<"\n"; return os; } void Frame::print() const { - std::cout<<"labels filename: "< &images,const int classes,const float IoU_t std::vector dets_classes_count(classes,0); //count groundtruth and detections in total and for each class - for(auto i:images) - { + for(auto i:images){ for(auto gt:i.gt) truth_classes_count[gt.cl]++; for(auto det:i.det) @@ -116,8 +114,7 @@ double computeMap(std::vector &images,const int classes,const float IoU_t groundtruths_count += i.gt.size(); } - if(verbose) - { + if(verbose){ std::cout<<"gt_count: "< &images,const int classes,const float IoU_t // for each detection comput IoU with groundtruth and match detetcion and // groundtruth with IoU greater than IoU_thresh - for(auto &img:images) - { - for(size_t i=0; i conf_thresh) - { + for(auto &img:images){ + for(size_t i=0; i conf_thresh){ float maxIoU = 0; int truth_index = -1; - for(size_t j=0; j maxIoU && img.det[i].cl == img.gt[j].cl) - { + if(currentIoU > maxIoU && img.det[i].cl == img.gt[j].cl){ maxIoU = currentIoU; truth_index = j; } } // std::cout<<"det i:"< -1 && maxIoU > IoU_thresh) - { + if(truth_index > -1 && maxIoU > IoU_thresh){ // std::cout<<"(INSIDE) IoU thresh:"< IoU_thresh:"<<(maxIoU > IoU_thresh)< &images,const int classes,const float IoU_t gt_checked += img.gt.size(); } - if(verbose) - { + if(verbose){ for(auto img:images) img.print(); std::cout<<"\n\n\n\n"; @@ -178,30 +168,24 @@ double computeMap(std::vector &images,const int classes,const float IoU_t //compute precision-recall curve std::vector> pr( classes, std::vector(detections_count)); - for(int rank = 0; rank< detections_count; ++rank) - { - if (rank > 0) - { - for (int class_id = 0; class_id < classes; ++class_id) - { + for(int rank = 0; rank< detections_count; ++rank){ + if (rank > 0) { + for (int class_id = 0; class_id < classes; ++class_id) { pr[class_id][rank].tp = pr[class_id][rank - 1].tp; pr[class_id][rank].fp = pr[class_id][rank - 1].fp; } } //if it was detected and never detected before - if (all_dets[rank].truth_flag == 1 && truth_flags[all_dets[rank].unique_truth_index] == 0) - { - truth_flags[all_dets[rank].unique_truth_index] = 1; + if (all_dets[rank].truthFlag == 1 && truth_flags[all_dets[rank].uniqueTruthIndex] == 0) { + truth_flags[all_dets[rank].uniqueTruthIndex] = 1; pr[all_dets[rank].cl][rank].tp++; // true-positive } - else - { + else { pr[all_dets[rank].cl][rank].fp++; // false-positive } - for (int i = 0; i < classes; ++i) - { + for (int i = 0; i < classes; ++i){ const int tp = pr[i][rank].tp; const int fp = pr[i][rank].fp; const int fn = truth_classes_count[i] - tp; // false-negative = objects - true-positive @@ -217,17 +201,15 @@ double computeMap(std::vector &images,const int classes,const float IoU_t else pr[i][rank].recall = 0; - if (rank == (detections_count - 1) && dets_classes_count[i] != (tp + fp)) - { // check for last rank + if (rank == (detections_count - 1) && dets_classes_count[i] != (tp + fp)) { + // check for last rank printf(" class_id: %d - detections = %d, tp+fp = %d, tp = %d, fp = %d \n", i, dets_classes_count[i], tp+fp, tp, fp); } } } - if(verbose) - { - for(int i=0; i < pr.size(); i++) - { + if(verbose){ + for(int i=0; i < pr.size(); i++) { std::cout<<"---------Class "< &images,const int classes,const float IoU_t double last_recall, last_precision, delta_recall; double cur_recall, cur_precision; double avg_precision = 0; - for (int i = 0; i < classes; ++i) - { + for (int i = 0; i < classes; ++i) { avg_precision = 0; - if (map_points == 0) //mAP calculation: ImageNet, PascalVOC 2010-2012 - { + if (map_points == 0){ //mAP calculation: ImageNet, PascalVOC 2010-2012 last_recall = pr[i][detections_count - 1].recall; last_precision = pr[i][detections_count - 1].precision; - for (int rank = detections_count - 2; rank >= 0; --rank) - { + for (int rank = detections_count - 2; rank >= 0; --rank){ delta_recall = last_recall - pr[i][rank].recall; last_recall = pr[i][rank].recall; @@ -259,8 +238,7 @@ double computeMap(std::vector &images,const int classes,const float IoU_t avg_precision += delta_recall * last_precision; } } - else //MSCOCO - 101 Recall-points, PascalVOC - 11 Recall-points - { + else {//MSCOCO - 101 Recall-points, PascalVOC - 11 Recall-points for (int point = 0; point < map_points; ++point) { cur_recall = point * 1.0 / ( map_points - 1 ); cur_precision = 0; @@ -287,16 +265,14 @@ double computeMap(std::vector &images,const int classes,const float IoU_t double computeMapNIoULevels(std::vector &images,const int classes,const float i_IoU_thresh, const float conf_thresh, const int map_points, const float map_step, const int map_levels, const bool verbose, const bool write_on_file, std::string net) { std::ofstream out_file; - if(write_on_file) - { + if(write_on_file){ out_file.open("map.csv", std::ios_base::app); out_file< &images,const int classes,const f } AP/=map_levels; - if(write_on_file) - { - out_file< &images,const int classes,const float IoU_ { std::ofstream out_file; - if(write_on_file) - { - out_file.open("pr.csv", std::ios_base::app); + if(write_on_file){ + out_file.open("pr.csv", std::ios_base::app); out_file< &images,const int classes,const float IoU_ std::vector dets_classes_count(classes,0); std::vector pr(classes); - for(auto &img:images) - { + for(auto &img:images){ for(auto& tc: truth_classes_count) tc = 0; for(auto& dc: dets_classes_count) dc = 0; std::vector det_assigned(img.det.size(), false); - for(size_t j=0; j conf_thresh) - { + for(size_t i=0; i conf_thresh){ float currentIoU = boxIoU(img.det[i], img.gt[j]); - if(currentIoU > maxIoU && img.det[i].cl == img.gt[j].cl && !det_assigned[i]) - { + if(currentIoU > maxIoU && img.det[i].cl == img.gt[j].cl && !det_assigned[i]){ maxIoU = currentIoU; det_index = i; } } } - if(det_index > -1 && maxIoU > IoU_thresh && !det_assigned[det_index]) - { - img.det[det_index].unique_truth_index = j; - img.det[det_index].truth_flag = 1; - img.det[det_index].max_IoU = maxIoU; + if(det_index > -1 && maxIoU > IoU_thresh && !det_assigned[det_index]){ + img.det[det_index].uniqueTruthIndex = j; + img.det[det_index].truthFlag = 1; + img.det[det_index].maxIoU = maxIoU; det_assigned[det_index] = true; dets_classes_count[img.det[det_index].cl]++; } } - for(size_t i=0; i &images,const int classes,const float IoU_ int TP = 0, FP = 0, FN = 0; - for(size_t i=0; i 0 ? (double)pr[i].tp / (double)(pr[i].tp +pr[i].fp) : 0; pr[i].recall = (pr[i].tp + pr[i].fn) > 0 ? (double)pr[i].tp / (double)(pr[i].tp +pr[i].fn) : 0; if(verbose) @@ -392,22 +357,21 @@ void computeTPFPFN(std::vector &images,const int classes,const float IoU_ avg_precision += pr[i].precision; avg_recall += pr[i].recall; - TP += pr[i].tp; - FP += pr[i].fp; - FN += pr[i].fn; + TP += pr[i].tp; + FP += pr[i].fp; + FN += pr[i].fn; } avg_precision /= classes; avg_recall /= classes; f1_score = avg_precision + avg_recall > 0 ? 2 * ( avg_precision * avg_recall ) / ( avg_precision + avg_recall ) : 0; - if(write_on_file) - { - out_file<