Commit bf17972881c559482e56cb89ffc898df48eaeaab
Merge pull request #283 from biometrics/evaluation_updates
Updates to eval_detection
Showing
5 changed files
with
110 additions
and
56 deletions
app/br/br.cpp
| @@ -160,8 +160,8 @@ public: | @@ -160,8 +160,8 @@ public: | ||
| 160 | check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'evalClustering'."); | 160 | check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'evalClustering'."); |
| 161 | br_eval_clustering(parv[0], parv[1], parc == 3 ? parv[2] : ""); | 161 | br_eval_clustering(parv[0], parv[1], parc == 3 ? parv[2] : ""); |
| 162 | } else if (!strcmp(fun, "evalDetection")) { | 162 | } else if (!strcmp(fun, "evalDetection")) { |
| 163 | - check((parc >= 2) && (parc <= 5), "Incorrect parameter count for 'evalDetection'."); | ||
| 164 | - br_eval_detection(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? atoi(parv[3]) : 0, parc == 5 ? atoi(parv[4]) : 0); | 163 | + check((parc >= 2) && (parc <= 6), "Incorrect parameter count for 'evalDetection'."); |
| 164 | + br_eval_detection(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? atoi(parv[3]) : 0, parc >= 5 ? atoi(parv[4]) : 0, parc == 6 ? atoi(parv[5]) : 0); | ||
| 165 | } else if (!strcmp(fun, "evalLandmarking")) { | 165 | } else if (!strcmp(fun, "evalLandmarking")) { |
| 166 | check((parc >= 2) && (parc <= 5), "Incorrect parameter count for 'evalLandmarking'."); | 166 | check((parc >= 2) && (parc <= 5), "Incorrect parameter count for 'evalLandmarking'."); |
| 167 | br_eval_landmarking(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? atoi(parv[3]) : 0, parc >= 5 ? atoi(parv[4]) : 1); | 167 | br_eval_landmarking(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? atoi(parv[3]) : 0, parc >= 5 ? atoi(parv[4]) : 1); |
openbr/core/eval.cpp
| @@ -666,10 +666,15 @@ struct Detection | @@ -666,10 +666,15 @@ struct Detection | ||
| 666 | { | 666 | { |
| 667 | QRectF boundingBox; | 667 | QRectF boundingBox; |
| 668 | float confidence; | 668 | float confidence; |
| 669 | + // The ignore flag is useful when certain faces in an image should be ignored | ||
| 670 | + // and should not effect detection performance. Predicted detections that overlap | ||
| 671 | + // with an ignored truth detection will not count as a true positive, false positive, | ||
| 672 | + // true negative, or false negative, it will simply be ignored. | ||
| 673 | + bool ignore; | ||
| 669 | 674 | ||
| 670 | Detection() {} | 675 | Detection() {} |
| 671 | - Detection(const QRectF &boundingBox_, float confidence_ = -1) | ||
| 672 | - : boundingBox(boundingBox_), confidence(confidence_) {} | 676 | + Detection(const QRectF &boundingBox_, float confidence_ = -1, bool ignore_ = false) |
| 677 | + : boundingBox(boundingBox_), confidence(confidence_), ignore(ignore_) {} | ||
| 673 | 678 | ||
| 674 | float area() const { return boundingBox.width() * boundingBox.height(); } | 679 | float area() const { return boundingBox.width() * boundingBox.height(); } |
| 675 | float overlap(const Detection &other) const | 680 | float overlap(const Detection &other) const |
| @@ -679,6 +684,16 @@ struct Detection | @@ -679,6 +684,16 @@ struct Detection | ||
| 679 | } | 684 | } |
| 680 | }; | 685 | }; |
| 681 | 686 | ||
| 687 | +struct SortedDetection | ||
| 688 | +{ | ||
| 689 | + int truth_idx, predicted_idx; | ||
| 690 | + float overlap; | ||
| 691 | + SortedDetection() : truth_idx(-1), predicted_idx(-1), overlap(-1) {} | ||
| 692 | + SortedDetection(int truth_idx_, int predicted_idx_, float overlap_) | ||
| 693 | + : truth_idx(truth_idx_), predicted_idx(predicted_idx_), overlap(overlap_) {} | ||
| 694 | + inline bool operator<(const SortedDetection &other) const { return overlap > other.overlap; } | ||
| 695 | +}; | ||
| 696 | + | ||
| 682 | struct Detections | 697 | struct Detections |
| 683 | { | 698 | { |
| 684 | QList<Detection> predicted, truth; | 699 | QList<Detection> predicted, truth; |
| @@ -704,6 +719,7 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec | @@ -704,6 +719,7 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec | ||
| 704 | { | 719 | { |
| 705 | QList<DetectionOperatingPoint> points; | 720 | QList<DetectionOperatingPoint> points; |
| 706 | float TP = 0, FP = 0, prevFP = -1; | 721 | float TP = 0, FP = 0, prevFP = -1; |
| 722 | + | ||
| 707 | for (int i=0; i<detections.size(); i++) { | 723 | for (int i=0; i<detections.size(); i++) { |
| 708 | const ResolvedDetection &detection = detections[i]; | 724 | const ResolvedDetection &detection = detections[i]; |
| 709 | if (discrete) { | 725 | if (discrete) { |
| @@ -716,6 +732,13 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec | @@ -716,6 +732,13 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec | ||
| 716 | } | 732 | } |
| 717 | if ((i == detections.size()-1) || (detection.confidence > detections[i+1].confidence)) { | 733 | if ((i == detections.size()-1) || (detection.confidence > detections[i+1].confidence)) { |
| 718 | if (FP > prevFP || (i == detections.size()-1)) { | 734 | if (FP > prevFP || (i == detections.size()-1)) { |
| 735 | + if (prevFP / numImages < 0.1 && FP / numImages > 0.1 && discrete) { | ||
| 736 | + qDebug("TAR @ FAR => %f : 0.1", TP / totalTrueDetections); | ||
| 737 | + qDebug("Confidence: %f", detection.confidence); | ||
| 738 | + } else if (prevFP / numImages < 0.01 && FP / numImages > 0.01 && discrete) { | ||
| 739 | + qDebug("TAR @ FAR => %f : 0.01", TP / totalTrueDetections); | ||
| 740 | + qDebug("Confidence: %f", detection.confidence); | ||
| 741 | + } | ||
| 719 | points.append(DetectionOperatingPoint(TP, FP, totalTrueDetections, numImages)); | 742 | points.append(DetectionOperatingPoint(TP, FP, totalTrueDetections, numImages)); |
| 720 | prevFP = FP; | 743 | prevFP = FP; |
| 721 | } | 744 | } |
| @@ -803,7 +826,7 @@ static QList<Detection> getDetections(const DetectionKey &key, const File &f, bo | @@ -803,7 +826,7 @@ static QList<Detection> getDetections(const DetectionKey &key, const File &f, bo | ||
| 803 | dets.append(Detection(f.get<QRectF>(key), isTruth ? -1 : f.get<float>("Confidence", -1))); | 826 | dets.append(Detection(f.get<QRectF>(key), isTruth ? -1 : f.get<float>("Confidence", -1))); |
| 804 | } else if (key.type == DetectionKey::XYWidthHeight) { | 827 | } else if (key.type == DetectionKey::XYWidthHeight) { |
| 805 | const QRectF rect(f.get<float>(key+"_X"), f.get<float>(key+"_Y"), f.get<float>(key+"_Width"), f.get<float>(key+"_Height")); | 828 | const QRectF rect(f.get<float>(key+"_X"), f.get<float>(key+"_Y"), f.get<float>(key+"_Width"), f.get<float>(key+"_Height")); |
| 806 | - dets.append(Detection(rect, isTruth ? -1 : f.get<float>("Confidence", -1))); | 829 | + dets.append(Detection(rect, isTruth ? -1 : f.get<float>("Confidence", -1), f.get<bool>("Ignore", false))); |
| 807 | } | 830 | } |
| 808 | return dets; | 831 | return dets; |
| 809 | } | 832 | } |
| @@ -827,21 +850,16 @@ static QMap<QString, Detections> getDetections(const File &predictedGallery, con | @@ -827,21 +850,16 @@ static QMap<QString, Detections> getDetections(const File &predictedGallery, con | ||
| 827 | qPrintable(predictedDetectKey == truthDetectKey ? QString() : "/"+truthDetectKey)); | 850 | qPrintable(predictedDetectKey == truthDetectKey ? QString() : "/"+truthDetectKey)); |
| 828 | 851 | ||
| 829 | QMap<QString, Detections> allDetections; | 852 | QMap<QString, Detections> allDetections; |
| 830 | - foreach (const File &f, predicted) | ||
| 831 | - allDetections[f.baseName()].predicted.append(getDetections(predictedDetectKey, f, false)); | ||
| 832 | foreach (const File &f, truth) | 853 | foreach (const File &f, truth) |
| 833 | - allDetections[f.baseName()].truth.append(getDetections(truthDetectKey, f, true)); | 854 | + allDetections[f.name].truth.append(getDetections(truthDetectKey, f, true)); |
| 855 | + foreach (const File &f, predicted) | ||
| 856 | + if (allDetections.contains(f.name)) allDetections[f.name].predicted.append(getDetections(predictedDetectKey, f, false)); | ||
| 834 | return allDetections; | 857 | return allDetections; |
| 835 | } | 858 | } |
| 836 | 859 | ||
| 837 | -static int getNumberOfImages(const File &truthGallery) | ||
| 838 | -{ | ||
| 839 | - const FileList files = FileList::fromGallery(truthGallery); | ||
| 840 | - | ||
| 841 | - QSet<QString> names; | ||
| 842 | - foreach(const File &file, files) | ||
| 843 | - names.insert(file.fileName()); | ||
| 844 | - return names.size(); | 860 | +static inline int getNumberOfImages(const QMap<QString, Detections> detections) |
| 861 | +{ | ||
| 862 | + return detections.keys().size(); | ||
| 845 | } | 863 | } |
| 846 | 864 | ||
| 847 | static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QList<ResolvedDetection> &falseNegative, QMap<QString, Detections> &all, QRectF &offsets) | 865 | static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QList<ResolvedDetection> &falseNegative, QMap<QString, Detections> &all, QRectF &offsets) |
| @@ -852,13 +870,13 @@ static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QL | @@ -852,13 +870,13 @@ static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QL | ||
| 852 | foreach (Detections detections, all.values()) { | 870 | foreach (Detections detections, all.values()) { |
| 853 | totalTrueDetections += detections.truth.size(); | 871 | totalTrueDetections += detections.truth.size(); |
| 854 | // Try to associate ground truth detections with predicted detections | 872 | // Try to associate ground truth detections with predicted detections |
| 855 | - while (!detections.truth.isEmpty() && !detections.predicted.isEmpty()) { | ||
| 856 | - const Detection truth = detections.truth.takeFirst(); // Take removes the detection | ||
| 857 | - int bestIndex = -1; | ||
| 858 | - float bestOverlap = -std::numeric_limits<float>::max(); | ||
| 859 | - // Find the nearest predicted detection to this ground truth detection | ||
| 860 | - for (int i=0; i<detections.predicted.size(); i++) { | ||
| 861 | - Detection predicted = detections.predicted[i]; | 873 | + |
| 874 | + QList<SortedDetection> sortedDetections; sortedDetections.reserve(detections.truth.size() * detections.predicted.size()); | ||
| 875 | + for (int t = 0; t < detections.truth.size(); t++) { | ||
| 876 | + const Detection truth = detections.truth[t]; | ||
| 877 | + for (int p = 0; p < detections.predicted.size(); p++) { | ||
| 878 | + Detection predicted = detections.predicted[p]; | ||
| 879 | + | ||
| 862 | float predictedWidth = predicted.boundingBox.width(); | 880 | float predictedWidth = predicted.boundingBox.width(); |
| 863 | float x, y, width, height; | 881 | float x, y, width, height; |
| 864 | x = predicted.boundingBox.x() + offsets.x()*predictedWidth; | 882 | x = predicted.boundingBox.x() + offsets.x()*predictedWidth; |
| @@ -868,35 +886,44 @@ static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QL | @@ -868,35 +886,44 @@ static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QL | ||
| 868 | Detection newPredicted(QRectF(x, y, width, height), 0.0); | 886 | Detection newPredicted(QRectF(x, y, width, height), 0.0); |
| 869 | 887 | ||
| 870 | const float overlap = truth.overlap(newPredicted); | 888 | const float overlap = truth.overlap(newPredicted); |
| 871 | - if (overlap > bestOverlap) { | ||
| 872 | - bestOverlap = overlap; | ||
| 873 | - bestIndex = i; | ||
| 874 | - } | 889 | + if (overlap > 0) |
| 890 | + sortedDetections.append(SortedDetection(t, p, overlap)); | ||
| 875 | } | 891 | } |
| 876 | - // Removing the detection prevents us from considering it twice. | ||
| 877 | - // We don't want to associate two ground truth detections with the | ||
| 878 | - // same prediction, over vice versa. | ||
| 879 | - const Detection predicted = detections.predicted.takeAt(bestIndex); | ||
| 880 | - resolved.append(ResolvedDetection(predicted.confidence, bestOverlap)); | ||
| 881 | - | ||
| 882 | - if (offsets.x() == 0) { | ||
| 883 | - // Add side differences to total only for pairs that meet the overlap threshold. | ||
| 884 | - if (bestOverlap > 0.3) { | ||
| 885 | - count++; | ||
| 886 | - float width = predicted.boundingBox.width(); | ||
| 887 | - dLeftTotal += (truth.boundingBox.left() - predicted.boundingBox.left()) / width; | ||
| 888 | - dRightTotal += (truth.boundingBox.right() - predicted.boundingBox.right()) / width; | ||
| 889 | - dTopTotal += (truth.boundingBox.top() - predicted.boundingBox.top()) / width; | ||
| 890 | - dBottomTotal += (truth.boundingBox.bottom() - predicted.boundingBox.bottom()) / width; | ||
| 891 | - } | 892 | + } |
| 893 | + | ||
| 894 | + std::sort(sortedDetections.begin(), sortedDetections.end()); | ||
| 895 | + | ||
| 896 | + QList<int> removedTruth; | ||
| 897 | + QList<int> removedPredicted; | ||
| 898 | + | ||
| 899 | + foreach (const SortedDetection &detection, sortedDetections) { | ||
| 900 | + if (removedTruth.contains(detection.truth_idx) || removedPredicted.contains(detection.predicted_idx)) | ||
| 901 | + continue; | ||
| 902 | + | ||
| 903 | + const Detection truth = detections.truth[detection.truth_idx]; | ||
| 904 | + const Detection predicted = detections.predicted[detection.predicted_idx]; | ||
| 905 | + | ||
| 906 | + if (!truth.ignore) resolved.append(ResolvedDetection(predicted.confidence, detection.overlap)); | ||
| 907 | + | ||
| 908 | + removedTruth.append(detection.truth_idx); | ||
| 909 | + removedPredicted.append(detection.predicted_idx); | ||
| 910 | + | ||
| 911 | + if (offsets.x() == 0 && detection.overlap > 0.3) { | ||
| 912 | + count++; | ||
| 913 | + float width = predicted.boundingBox.width(); | ||
| 914 | + dLeftTotal += (truth.boundingBox.left() - predicted.boundingBox.left()) / width; | ||
| 915 | + dRightTotal += (truth.boundingBox.right() - predicted.boundingBox.right()) / width; | ||
| 916 | + dTopTotal += (truth.boundingBox.top() - predicted.boundingBox.top()) / width; | ||
| 917 | + dBottomTotal += (truth.boundingBox.bottom() - predicted.boundingBox.bottom()) / width; | ||
| 892 | } | 918 | } |
| 893 | } | 919 | } |
| 894 | 920 | ||
| 895 | - foreach (const Detection &detection, detections.predicted) | ||
| 896 | - resolved.append(ResolvedDetection(detection.confidence, 0)); | ||
| 897 | - for (int i=0; i<detections.truth.size(); i++) | ||
| 898 | - falseNegative.append(ResolvedDetection(-std::numeric_limits<float>::max(), 0)); | 921 | + for (int i = 0; i < detections.predicted.size(); i++) |
| 922 | + if (!removedPredicted.contains(i)) resolved.append(ResolvedDetection(detections.predicted[i].confidence, 0)); | ||
| 923 | + for (int i = 0; i < detections.truth.size(); i++) | ||
| 924 | + if (!removedTruth.contains(i) && !detections.truth[i].ignore) falseNegative.append(ResolvedDetection(-std::numeric_limits<float>::max(), 0)); | ||
| 899 | } | 925 | } |
| 926 | + | ||
| 900 | if (offsets.x() == 0) { | 927 | if (offsets.x() == 0) { |
| 901 | // Calculate average differences in each direction | 928 | // Calculate average differences in each direction |
| 902 | float dRight = dRightTotal / count; | 929 | float dRight = dRightTotal / count; |
| @@ -914,7 +941,7 @@ static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QL | @@ -914,7 +941,7 @@ static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QL | ||
| 914 | return totalTrueDetections; | 941 | return totalTrueDetections; |
| 915 | } | 942 | } |
| 916 | 943 | ||
| 917 | -float EvalDetection(const QString &predictedGallery, const QString &truthGallery, const QString &csv, bool normalize, int minSize) | 944 | +float EvalDetection(const QString &predictedGallery, const QString &truthGallery, const QString &csv, bool normalize, int minSize, int maxSize) |
| 918 | { | 945 | { |
| 919 | qDebug("Evaluating detection of %s against %s", qPrintable(predictedGallery), qPrintable(truthGallery)); | 946 | qDebug("Evaluating detection of %s against %s", qPrintable(predictedGallery), qPrintable(truthGallery)); |
| 920 | // Organized by file, QMap used to preserve order | 947 | // Organized by file, QMap used to preserve order |
| @@ -923,12 +950,13 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | @@ -923,12 +950,13 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | ||
| 923 | // Remove any bounding boxes with a side smaller than minSize | 950 | // Remove any bounding boxes with a side smaller than minSize |
| 924 | if (minSize > 0) { | 951 | if (minSize > 0) { |
| 925 | qDebug("Removing boxes smaller than %d\n", minSize); | 952 | qDebug("Removing boxes smaller than %d\n", minSize); |
| 953 | + QMap<QString, Detections> allFilteredDetections; | ||
| 926 | foreach (QString key, allDetections.keys()) { | 954 | foreach (QString key, allDetections.keys()) { |
| 927 | Detections detections = allDetections[key]; | 955 | Detections detections = allDetections[key]; |
| 928 | Detections filteredDetections; | 956 | Detections filteredDetections; |
| 929 | for (int i = 0; i < detections.predicted.size(); i++) { | 957 | for (int i = 0; i < detections.predicted.size(); i++) { |
| 930 | QRectF box = detections.predicted[i].boundingBox; | 958 | QRectF box = detections.predicted[i].boundingBox; |
| 931 | - if (min(box.width(), box.height()) > minSize) { | 959 | + if (min(box.width(), box.height()) > sqrt(0.5 * pow(minSize, 2))) { |
| 932 | filteredDetections.predicted.append(detections.predicted[i]); | 960 | filteredDetections.predicted.append(detections.predicted[i]); |
| 933 | } | 961 | } |
| 934 | } | 962 | } |
| @@ -939,8 +967,34 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | @@ -939,8 +967,34 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | ||
| 939 | filteredDetections.truth.append(detections.truth[i]); | 967 | filteredDetections.truth.append(detections.truth[i]); |
| 940 | } | 968 | } |
| 941 | } | 969 | } |
| 942 | - allDetections.insert(key, filteredDetections); | 970 | + if (!filteredDetections.truth.empty()) allFilteredDetections[key] = filteredDetections; |
| 971 | + } | ||
| 972 | + allDetections = allFilteredDetections; | ||
| 973 | + } | ||
| 974 | + | ||
| 975 | + // Remove any bounding boxes with no side smaller than maxSize | ||
| 976 | + if (maxSize > 0) { | ||
| 977 | + qDebug("Removing boxes larger than %d\n", maxSize); | ||
| 978 | + QMap<QString, Detections> allFilteredDetections; | ||
| 979 | + foreach (QString key, allDetections.keys()) { | ||
| 980 | + Detections detections = allDetections[key]; | ||
| 981 | + Detections filteredDetections; | ||
| 982 | + for (int i = 0; i < detections.predicted.size(); i++) { | ||
| 983 | + QRectF box = detections.predicted[i].boundingBox; | ||
| 984 | + if (min(box.width(), box.height()) < sqrt(0.5 * pow(maxSize, 2))) { | ||
| 985 | + filteredDetections.predicted.append(detections.predicted[i]); | ||
| 986 | + } | ||
| 987 | + } | ||
| 988 | + | ||
| 989 | + for (int i = 0; i < detections.truth.size(); i++) { | ||
| 990 | + QRectF box = detections.truth[i].boundingBox; | ||
| 991 | + if (min(box.width(), box.height()) < maxSize) { | ||
| 992 | + filteredDetections.truth.append(detections.truth[i]); | ||
| 993 | + } | ||
| 994 | + } | ||
| 995 | + if (!filteredDetections.truth.empty()) allFilteredDetections[key] = filteredDetections; | ||
| 943 | } | 996 | } |
| 997 | + allDetections = allFilteredDetections; | ||
| 944 | } | 998 | } |
| 945 | 999 | ||
| 946 | QList<ResolvedDetection> resolvedDetections, falseNegativeDetections; | 1000 | QList<ResolvedDetection> resolvedDetections, falseNegativeDetections; |
| @@ -963,8 +1017,8 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | @@ -963,8 +1017,8 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | ||
| 963 | std::sort(resolvedDetections.begin(), resolvedDetections.end()); | 1017 | std::sort(resolvedDetections.begin(), resolvedDetections.end()); |
| 964 | QStringList lines; | 1018 | QStringList lines; |
| 965 | lines.append("Plot, X, Y"); | 1019 | lines.append("Plot, X, Y"); |
| 966 | - lines.append(computeDetectionResults(resolvedDetections, totalTrueDetections, getNumberOfImages(truthGallery), true)); | ||
| 967 | - lines.append(computeDetectionResults(resolvedDetections, totalTrueDetections, getNumberOfImages(truthGallery), false)); | 1020 | + lines.append(computeDetectionResults(resolvedDetections, totalTrueDetections, getNumberOfImages(allDetections), true)); |
| 1021 | + lines.append(computeDetectionResults(resolvedDetections, totalTrueDetections, getNumberOfImages(allDetections), false)); | ||
| 968 | 1022 | ||
| 969 | float averageOverlap; | 1023 | float averageOverlap; |
| 970 | { // Overlap Density | 1024 | { // Overlap Density |
openbr/core/eval.h
| @@ -30,7 +30,7 @@ namespace br | @@ -30,7 +30,7 @@ namespace br | ||
| 30 | float InplaceEval(const QString & simmat, const QString & target, const QString & query, const QString & csv = ""); | 30 | float InplaceEval(const QString & simmat, const QString & target, const QString & query, const QString & csv = ""); |
| 31 | 31 | ||
| 32 | void EvalClassification(const QString &predictedGallery, const QString &truthGallery, QString predictedProperty = "", QString truthProperty = ""); | 32 | void EvalClassification(const QString &predictedGallery, const QString &truthGallery, QString predictedProperty = "", QString truthProperty = ""); |
| 33 | - float EvalDetection(const QString &predictedGallery, const QString &truthGallery, const QString &csv = "", bool normalize = false, int minSize = 0); // Return average overlap | 33 | + float EvalDetection(const QString &predictedGallery, const QString &truthGallery, const QString &csv = "", bool normalize = false, int minSize = 0, int maxSize = 0); // Return average overlap |
| 34 | float EvalLandmarking(const QString &predictedGallery, const QString &truthGallery, const QString &csv = "", int normalizationIndexA = 0, int normalizationIndexB = 1); // Return average error | 34 | float EvalLandmarking(const QString &predictedGallery, const QString &truthGallery, const QString &csv = "", int normalizationIndexA = 0, int normalizationIndexB = 1); // Return average error |
| 35 | void EvalRegression(const QString &predictedGallery, const QString &truthGallery, QString predictedProperty = "", QString truthProperty = ""); | 35 | void EvalRegression(const QString &predictedGallery, const QString &truthGallery, QString predictedProperty = "", QString truthProperty = ""); |
| 36 | } | 36 | } |
openbr/openbr.cpp
| @@ -129,9 +129,9 @@ void br_eval_clustering(const char *csv, const char *gallery, const char *truth_ | @@ -129,9 +129,9 @@ void br_eval_clustering(const char *csv, const char *gallery, const char *truth_ | ||
| 129 | EvalClustering(csv, gallery, truth_property); | 129 | EvalClustering(csv, gallery, truth_property); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | -float br_eval_detection(const char *predicted_gallery, const char *truth_gallery, const char *csv, bool normalize, int minSize) | 132 | +float br_eval_detection(const char *predicted_gallery, const char *truth_gallery, const char *csv, bool normalize, int minSize, int maxSize) |
| 133 | { | 133 | { |
| 134 | - return EvalDetection(predicted_gallery, truth_gallery, csv, normalize, minSize); | 134 | + return EvalDetection(predicted_gallery, truth_gallery, csv, normalize, minSize, maxSize); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | float br_eval_landmarking(const char *predicted_gallery, const char *truth_gallery, const char *csv, int normalization_index_a, int normalization_index_b) | 137 | float br_eval_landmarking(const char *predicted_gallery, const char *truth_gallery, const char *csv, int normalization_index_a, int normalization_index_b) |
openbr/openbr.h
| @@ -205,7 +205,7 @@ BR_EXPORT void br_eval_clustering(const char *csv, const char *gallery, const ch | @@ -205,7 +205,7 @@ BR_EXPORT void br_eval_clustering(const char *csv, const char *gallery, const ch | ||
| 205 | * \param normalize Optional \c bool flag to normalize predicted bounding boxes for improved detection. | 205 | * \param normalize Optional \c bool flag to normalize predicted bounding boxes for improved detection. |
| 206 | * \return Average detection bounding box overlap. | 206 | * \return Average detection bounding box overlap. |
| 207 | */ | 207 | */ |
| 208 | -BR_EXPORT float br_eval_detection(const char *predicted_gallery, const char *truth_gallery, const char *csv = "", bool normalize = false, int minSize = 0); | 208 | +BR_EXPORT float br_eval_detection(const char *predicted_gallery, const char *truth_gallery, const char *csv = "", bool normalize = false, int minSize = 0, int maxSize = 0); |
| 209 | 209 | ||
| 210 | /*! | 210 | /*! |
| 211 | * \brief Evaluates and prints landmarking accuracy to terminal. | 211 | * \brief Evaluates and prints landmarking accuracy to terminal. |