diff --git a/dlib/svm/structural_object_detection_trainer.h b/dlib/svm/structural_object_detection_trainer.h index abd393665..ada4b2613 100644 --- a/dlib/svm/structural_object_detection_trainer.h +++ b/dlib/svm/structural_object_detection_trainer.h @@ -45,7 +45,7 @@ namespace dlib eps = 0.3; num_threads = 2; max_cache_size = 40; - overlap_eps = 0.5; + match_eps = 0.5; loss_per_missed_target = 1; loss_per_false_alarm = 1; @@ -155,25 +155,25 @@ namespace dlib return C; } - void set_overlap_eps ( + void set_match_eps ( double eps ) { // make sure requires clause is not broken DLIB_ASSERT(0 < eps && eps < 1, - "\t void structural_object_detection_trainer::set_overlap_eps(eps)" + "\t void structural_object_detection_trainer::set_match_eps(eps)" << "\n\t Invalid inputs were given to this function " << "\n\t eps: " << eps << "\n\t this: " << this ); - overlap_eps = eps; + match_eps = eps; } - double get_overlap_eps ( + double get_match_eps ( ) const { - return overlap_eps; + return match_eps; } double get_loss_per_missed_target ( @@ -244,7 +244,7 @@ namespace dlib svm_prob.set_c(C); svm_prob.set_epsilon(eps); svm_prob.set_max_cache_size(max_cache_size); - svm_prob.set_overlap_eps(overlap_eps); + svm_prob.set_match_eps(match_eps); svm_prob.set_loss_per_missed_target(loss_per_missed_target); svm_prob.set_loss_per_false_alarm(loss_per_false_alarm); matrix w; @@ -265,7 +265,7 @@ namespace dlib double C; oca solver; double eps; - double overlap_eps; + double match_eps; bool verbose; unsigned long num_threads; unsigned long max_cache_size; diff --git a/dlib/svm/structural_object_detection_trainer_abstract.h b/dlib/svm/structural_object_detection_trainer_abstract.h index ce774bc84..f9253d5d7 100644 --- a/dlib/svm/structural_object_detection_trainer_abstract.h +++ b/dlib/svm/structural_object_detection_trainer_abstract.h @@ -55,7 +55,7 @@ namespace dlib - #get_epsilon() == 0.3 - #get_num_threads() == 2 - #get_max_cache_size() == 40 - - #get_overlap_eps() == 0.5 + - #get_match_eps() == 0.5 - #get_loss_per_missed_target() == 1 - #get_loss_per_false_alarm() == 1 - This object will attempt to learn a model for the given @@ -190,25 +190,25 @@ namespace dlib better generalization. !*/ - void set_overlap_eps ( + void set_match_eps ( double eps ); /*! requires - 0 < eps < 1 ensures - - #get_overlap_eps() == eps + - #get_match_eps() == eps !*/ - double get_overlap_eps ( + double get_match_eps ( ) const; /*! ensures - - returns the amount of overlap necessary for a detection to be considered - as overlapping with a ground truth rectangle. If it doesn't overlap then + - returns the amount of alignment necessary for a detection to be considered + as matching with a ground truth rectangle. If it doesn't match then it is considered to be a false alarm. To define this precisely, let - A and B be two rectangles, then A and B overlap if and only if: - A.intersect(B).area()/(A+B).area() > get_overlap_eps() + A and B be two rectangles, then A and B match if and only if: + A.intersect(B).area()/(A+B).area() > get_match_eps() !*/ double get_loss_per_missed_target ( diff --git a/dlib/svm/structural_svm_object_detection_problem.h b/dlib/svm/structural_svm_object_detection_problem.h index 802feac04..2deca21b1 100644 --- a/dlib/svm/structural_svm_object_detection_problem.h +++ b/dlib/svm/structural_svm_object_detection_problem.h @@ -43,7 +43,7 @@ namespace dlib boxes_overlap(overlap_tester), images(images_), truth_rects(truth_rects_), - overlap_eps(0.5), + match_eps(0.5), loss_per_false_alarm(1), loss_per_missed_target(1) { @@ -68,25 +68,25 @@ namespace dlib max_num_dets = max_num_dets*3 + 10; } - void set_overlap_eps ( + void set_match_eps ( double eps ) { // make sure requires clause is not broken DLIB_ASSERT(0 < eps && eps < 1, - "\t void structural_svm_object_detection_problem::set_overlap_eps(eps)" + "\t void structural_svm_object_detection_problem::set_match_eps(eps)" << "\n\t Invalid inputs were given to this function " << "\n\t eps: " << eps << "\n\t this: " << this ); - overlap_eps = eps; + match_eps = eps; } - double get_overlap_eps ( + double get_match_eps ( ) const { - return overlap_eps; + return match_eps; } double get_loss_per_missed_target ( @@ -199,25 +199,25 @@ namespace dlib } } - // make sure the mapped rectangles are within overlap_eps of the + // make sure the mapped rectangles are within match_eps of the // truth rectangles. for (unsigned long i = 0; i < mapped_rects.size(); ++i) { const double area = (truth_rects[idx][i].intersect(mapped_rects[i])).area(); const double total_area = (truth_rects[idx][i] + mapped_rects[i]).area(); - if (area/total_area <= overlap_eps) + if (area/total_area <= match_eps) { using namespace std; ostringstream sout; sout << "An impossible set of object labels was detected. This is happening because "; sout << "none of the sliding window detection templates is capable of matching the size "; - sout << "and/or shape of one of the ground truth rectangles to within the required overlap_eps "; - sout << "amount of overlap. To resolve this you need to either lower the overlap_eps, add "; + sout << "and/or shape of one of the ground truth rectangles to within the required match_eps "; + sout << "amount of alignment. To resolve this you need to either lower the match_eps, add "; sout << "another detection template which can match the offending rectangle, or adjust the "; sout << "offending truth rectangle so it can be matched by an existing detection template. "; sout << "It is also possible that the image pyramid you are using is too coarse. E.g. if one of "; - sout << "your existing detection templates has a matching width/height ratio and smaller area than the offending "; - sout << "rectangle then a finer image pyramid would probably help."; + sout << "your existing detection templates has a matching width/height ratio and smaller area "; + sout << "than the offending rectangle then a finer image pyramid would probably help."; // make sure the above string fits nicely into a command prompt window. @@ -225,8 +225,8 @@ namespace dlib sout.str(""); sout << wrap_string(temp,0,0) << endl << endl; sout << "image index "<< idx << endl; - sout << "overlap_eps: "<< overlap_eps << endl; - sout << "best possible overlap: "<< area/total_area << endl; + sout << "match_eps: "<< match_eps << endl; + sout << "best possible match: "<< area/total_area << endl; sout << "truth rect: "<< truth_rects[idx][i] << endl; sout << "truth rect width/height: "<< truth_rects[idx][i].width()/(double)truth_rects[idx][i].height() << endl; sout << "truth rect area: "<< truth_rects[idx][i].area() << endl; @@ -272,13 +272,13 @@ namespace dlib if (overlaps_any_box(final_dets, dets[i].second)) continue; - const std::pair truth = find_max_overlap(truth_rects[idx], dets[i].second); + const std::pair truth = find_best_match(truth_rects[idx], dets[i].second); final_dets.push_back(dets[i].second); - const double truth_overlap = truth.first; + const double truth_match = truth.first; // if hit truth rect - if (truth_overlap > overlap_eps) + if (truth_match > match_eps) { // if this is the first time we have seen a detect which hit truth_rects[truth.second] const double score = dets[i].first - thresh; @@ -302,10 +302,10 @@ namespace dlib if (overlaps_any_box(final_dets, dets[i].second)) continue; - const std::pair truth = find_max_overlap(truth_rects[idx], dets[i].second); + const std::pair truth = find_best_match(truth_rects[idx], dets[i].second); - const double truth_overlap = truth.first; - if (truth_overlap > overlap_eps) + const double truth_match = truth.first; + if (truth_match > match_eps) { if (truth_score_hits[truth.second] >= 0) { @@ -351,22 +351,22 @@ namespace dlib return false; } - std::pair find_max_overlap( + std::pair find_best_match( const std::vector& boxes, const rectangle rect ) const /*! ensures - - determines which rectangle in boxes overlaps rect the most and - returns the amount of this overlap. Specifically, the overlap is + - determines which rectangle in boxes matches rect the most and + returns the amount of this match. Specifically, the match is a number O with the following properties: - 0 <= O <= 1 - - Let R be the maximum overlap rectangle in boxes, then - O == (R.intersect(rect)).area() / (R + rect).area - - O == 0 if there is no overlap with any rectangle. + - Let R be the maximum matching rectangle in boxes, then + O == (R.intersect(rect)).area() / (R + rect).area() + - O == 0 if there is no match with any rectangle. !*/ { - double overlap = 0; + double match = 0; unsigned int best_idx = 0; for (unsigned long i = 0; i < boxes.size(); ++i) { @@ -374,16 +374,16 @@ namespace dlib const unsigned long area = rect.intersect(boxes[i]).area(); if (area != 0) { - const double new_overlap = area / static_cast((rect + boxes[i]).area()); - if (new_overlap > overlap) + const double new_match = area / static_cast((rect + boxes[i]).area()); + if (new_match > match) { - overlap = new_overlap; + match = new_match; best_idx = i; } } } - return std::make_pair(overlap,best_idx); + return std::make_pair(match,best_idx); } @@ -396,7 +396,7 @@ namespace dlib const std::vector >& truth_rects; unsigned long max_num_dets; - double overlap_eps; + double match_eps; double loss_per_false_alarm; double loss_per_missed_target; }; diff --git a/dlib/svm/structural_svm_object_detection_problem_abstract.h b/dlib/svm/structural_svm_object_detection_problem_abstract.h index d712f8485..c6dc9ba95 100644 --- a/dlib/svm/structural_svm_object_detection_problem_abstract.h +++ b/dlib/svm/structural_svm_object_detection_problem_abstract.h @@ -68,12 +68,12 @@ namespace dlib Then the loss for a particular labeling is the quantity: FA*get_loss_per_false_alarm() + MT*get_loss_per_missed_target() - A detection is considered a false alarm if it doesn't overlap with any + A detection is considered a false alarm if it doesn't match with any of the ground truth rectangles or if it is a duplicate detection of a - truth rectangle. Finally, for the purposes of calculating loss, overlap - is determined using the following formula, rectangles A and B overlap + truth rectangle. Finally, for the purposes of calculating loss, a match + is determined using the following formula, rectangles A and B match if and only if: - A.intersect(B).area()/(A+B).area() > get_overlap_eps() + A.intersect(B).area()/(A+B).area() > get_match_eps() !*/ public: @@ -98,7 +98,7 @@ namespace dlib object_detector detector(scanner,overlap_tester,w) results in a detector object which attempts to compute the following mapping: truth_rects[i] == detector(images[i]) - - #get_overlap_eps() == 0.5 + - #get_match_eps() == 0.5 - This object will use num_threads threads during the optimization procedure. You should set this parameter equal to the number of available processing cores on your machine. @@ -106,22 +106,25 @@ namespace dlib - #get_loss_per_false_alarm() == 1 !*/ - void set_overlap_eps ( + void set_match_eps ( double eps ); /*! requires - 0 < eps < 1 ensures - - #get_overlap_eps() == eps + - #get_match_eps() == eps !*/ - double get_overlap_eps ( + double get_match_eps ( ) const; /*! ensures - - returns the amount of overlap necessary for a detection to be considered - as overlapping with a ground truth rectangle. + - returns the amount of alignment necessary for a detection to be considered + as matching with a ground truth rectangle. The precise formula for determining + if two rectangles match each other is the following, rectangles A and B match + if and only if: + A.intersect(B).area()/(A+B).area() > get_match_eps() !*/ double get_loss_per_missed_target (