Commit bddd6a348b466134572ecfc445edc5552bed1926
Committed by
GitHub
Merge pull request #583 from biometrics/object_eval
Add the ability to match object labels in the detection evaluation
Showing
7 changed files
with
68 additions
and
21 deletions
app/br/br.cpp
| @@ -160,8 +160,8 @@ public: | @@ -160,8 +160,8 @@ public: | ||
| 160 | check((parc >= 2) && (parc <= 5), "Incorrect parameter count for 'evalClustering'."); | 160 | check((parc >= 2) && (parc <= 5), "Incorrect parameter count for 'evalClustering'."); |
| 161 | br_eval_clustering(parv[0], parv[1], parc > 2 ? parv[2] : "", parc > 3 ? atoi(parv[3]) : 1, parc > 4 ? parv[4] : ""); | 161 | br_eval_clustering(parv[0], parv[1], parc > 2 ? parv[2] : "", parc > 3 ? atoi(parv[3]) : 1, parc > 4 ? parv[4] : ""); |
| 162 | } else if (!strcmp(fun, "evalDetection")) { | 162 | } else if (!strcmp(fun, "evalDetection")) { |
| 163 | - check((parc >= 2) && (parc <= 7), "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, parc >= 7 ? atof(parv[6]) : 0); | 163 | + check((parc >= 2) && (parc <= 8), "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, parc >= 7 ? atof(parv[6]) : 0, parc >= 8 ? parv[7] : ""); | ||
| 165 | } else if (!strcmp(fun, "evalLandmarking")) { | 165 | } else if (!strcmp(fun, "evalLandmarking")) { |
| 166 | check((parc >= 2) && (parc <= 7), "Incorrect parameter count for 'evalLandmarking'."); | 166 | check((parc >= 2) && (parc <= 7), "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, parc >= 6 ? atoi(parv[5]) : 0, parc >= 7 ? atoi(parv[6]) : 5); | 167 | br_eval_landmarking(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? atoi(parv[3]) : 0, parc >= 5 ? atoi(parv[4]) : 1, parc >= 6 ? atoi(parv[5]) : 0, parc >= 7 ? atoi(parv[6]) : 5); |
| @@ -290,7 +290,7 @@ private: | @@ -290,7 +290,7 @@ private: | ||
| 290 | "-convert (Format|Gallery|Output) <input_file> {output_file}\n" | 290 | "-convert (Format|Gallery|Output) <input_file> {output_file}\n" |
| 291 | "-evalClassification <predicted_gallery> <truth_gallery> <predicted property name> <ground truth proprty name>\n" | 291 | "-evalClassification <predicted_gallery> <truth_gallery> <predicted property name> <ground truth proprty name>\n" |
| 292 | "-evalClustering <clusters> <truth_gallery> [truth_property [cluster_csv [cluster_property]]]\n" | 292 | "-evalClustering <clusters> <truth_gallery> [truth_property [cluster_csv [cluster_property]]]\n" |
| 293 | - "-evalDetection <predicted_gallery> <truth_gallery> [{csv}] [{normalize}] [{minSize}] [{maxSize}]\n" | 293 | + "-evalDetection <predicted_gallery> <truth_gallery> [{csv}] [{normalize}] [{minSize}] [{maxSize}] [{label_filter}]\n" |
| 294 | "-evalLandmarking <predicted_gallery> <truth_gallery> [{csv} [<normalization_index_a> <normalization_index_b>] [sample_index] [total_examples]]\n" | 294 | "-evalLandmarking <predicted_gallery> <truth_gallery> [{csv} [<normalization_index_a> <normalization_index_b>] [sample_index] [total_examples]]\n" |
| 295 | "-evalRegression <predicted_gallery> <truth_gallery> <predicted property name> <ground truth property name>\n" | 295 | "-evalRegression <predicted_gallery> <truth_gallery> <predicted property name> <ground truth property name>\n" |
| 296 | "-evalKNN <knn_graph> <knn_truth> [{csv}]\n" | 296 | "-evalKNN <knn_graph> <knn_truth> [{csv}]\n" |
openbr/core/eval.cpp
| @@ -769,7 +769,7 @@ void EvalClassification(const QString &predictedGallery, const QString &truthGal | @@ -769,7 +769,7 @@ void EvalClassification(const QString &predictedGallery, const QString &truthGal | ||
| 769 | qDebug("Overall Accuracy = %f", (float)tpc / (float)(tpc + fnc)); | 769 | qDebug("Overall Accuracy = %f", (float)tpc / (float)(tpc + fnc)); |
| 770 | } | 770 | } |
| 771 | 771 | ||
| 772 | -float EvalDetection(const QString &predictedGallery, const QString &truthGallery, const QString &csv, bool normalize, int minSize, int maxSize, float relativeMinSize) | 772 | +float EvalDetection(const QString &predictedGallery, const QString &truthGallery, const QString &csv, bool normalize, int minSize, int maxSize, float relativeMinSize, const QString &label) |
| 773 | { | 773 | { |
| 774 | qDebug("Evaluating detection of %s against %s", qPrintable(predictedGallery), qPrintable(truthGallery)); | 774 | qDebug("Evaluating detection of %s against %s", qPrintable(predictedGallery), qPrintable(truthGallery)); |
| 775 | // Organized by file, QMap used to preserve order | 775 | // Organized by file, QMap used to preserve order |
| @@ -789,6 +789,15 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | @@ -789,6 +789,15 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | ||
| 789 | allDetections = filterDetections(allDetections, maxSize, false); | 789 | allDetections = filterDetections(allDetections, maxSize, false); |
| 790 | } | 790 | } |
| 791 | 791 | ||
| 792 | + // Optionally, keep only detections with a specific label | ||
| 793 | + if (!label.isEmpty()) { | ||
| 794 | + if (Globals->verbose) | ||
| 795 | + qDebug("Removing detections without label %s\n", qPrintable(label)); | ||
| 796 | + allDetections = filterLabels(allDetections, label); | ||
| 797 | + if (allDetections.isEmpty()) | ||
| 798 | + qFatal("No detections left after filtering on label. Check your filter"); | ||
| 799 | + } | ||
| 800 | + | ||
| 792 | QList<ResolvedDetection> resolvedDetections, falseNegativeDetections; | 801 | QList<ResolvedDetection> resolvedDetections, falseNegativeDetections; |
| 793 | QRectF normalizations(0, 0, 0, 0); | 802 | QRectF normalizations(0, 0, 0, 0); |
| 794 | 803 |
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, int maxSize = 0, float relativeMinSize = 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, float relativeMinSize = 0, const QString &label = ""); // Return average overlap |
| 34 | float EvalLandmarking(const QString &predictedGallery, const QString &truthGallery, const QString &csv = "", int normalizationIndexA = 0, int normalizationIndexB = 1, int sampleIndex = 0, int totalExamples = 5); // Return average error | 34 | float EvalLandmarking(const QString &predictedGallery, const QString &truthGallery, const QString &csv = "", int normalizationIndexA = 0, int normalizationIndexB = 1, int sampleIndex = 0, int totalExamples = 5); // 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 | void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &csv = ""); | 36 | void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &csv = ""); |
openbr/core/evalutils.cpp
| @@ -47,28 +47,34 @@ DetectionKey EvalUtils::getDetectKey(const FileList &files) | @@ -47,28 +47,34 @@ DetectionKey EvalUtils::getDetectKey(const FileList &files) | ||
| 47 | // return a list of detections independent of the detection key format | 47 | // return a list of detections independent of the detection key format |
| 48 | QList<Detection> EvalUtils::getDetections(const DetectionKey &key, const File &f, bool isTruth) | 48 | QList<Detection> EvalUtils::getDetections(const DetectionKey &key, const File &f, bool isTruth) |
| 49 | { | 49 | { |
| 50 | - QString pose = f.get<QString>("Pose"); | 50 | + QString pose = f.get<QString>("Pose", "Frontal"); |
| 51 | if (pose.contains("Angle")) | 51 | if (pose.contains("Angle")) |
| 52 | pose = "Frontal"; | 52 | pose = "Frontal"; |
| 53 | 53 | ||
| 54 | + QString label = f.get<QString>("Label", ""); | ||
| 55 | + | ||
| 54 | const QString filePath = f.path() + "/" + f.fileName(); | 56 | const QString filePath = f.path() + "/" + f.fileName(); |
| 55 | QList<Detection> dets; | 57 | QList<Detection> dets; |
| 56 | if (key.type == DetectionKey::RectList) { | 58 | if (key.type == DetectionKey::RectList) { |
| 57 | QList<QRectF> rects = f.rects(); | 59 | QList<QRectF> rects = f.rects(); |
| 58 | QList<float> confidences = f.getList<float>("Confidences", QList<float>()); | 60 | QList<float> confidences = f.getList<float>("Confidences", QList<float>()); |
| 61 | + QList<QString> labels = f.getList<QString>("Labels", QList<QString>()); | ||
| 59 | if (!isTruth && rects.size() != confidences.size()) | 62 | if (!isTruth && rects.size() != confidences.size()) |
| 60 | qFatal("You don't have enough confidence. I mean, your detections don't all have confidence measures."); | 63 | qFatal("You don't have enough confidence. I mean, your detections don't all have confidence measures."); |
| 64 | + if (!labels.empty() && rects.size() != labels.size()) | ||
| 65 | + qFatal("Some of your rects have labels but not all, it's all or nothing I'm afraid"); | ||
| 66 | + | ||
| 61 | for (int i=0; i<rects.size(); i++) { | 67 | for (int i=0; i<rects.size(); i++) { |
| 62 | if (isTruth) | 68 | if (isTruth) |
| 63 | - dets.append(Detection(rects[i], filePath)); | 69 | + dets.append(Detection(rects[i], filePath, -1, false, "Frontal", labels.empty() ? "" : labels[i])); |
| 64 | else | 70 | else |
| 65 | - dets.append(Detection(rects[i], filePath, confidences[i])); | 71 | + dets.append(Detection(rects[i], filePath, confidences[i], false, "Frontal", labels.empty() ? "" : labels[i])); |
| 66 | } | 72 | } |
| 67 | } else if (key.type == DetectionKey::Rect) { | 73 | } else if (key.type == DetectionKey::Rect) { |
| 68 | - dets.append(Detection(f.get<QRectF>(key), filePath, isTruth ? -1 : f.get<float>("Confidence", -1), f.get<bool>("Ignore", false), pose)); | 74 | + dets.append(Detection(f.get<QRectF>(key), filePath, isTruth ? -1 : f.get<float>("Confidence", -1), f.get<bool>("Ignore", false), pose, label)); |
| 69 | } else if (key.type == DetectionKey::XYWidthHeight) { | 75 | } else if (key.type == DetectionKey::XYWidthHeight) { |
| 70 | const QRectF rect(f.get<float>(key+"_X"), f.get<float>(key+"_Y"), f.get<float>(key+"_Width"), f.get<float>(key+"_Height")); | 76 | const QRectF rect(f.get<float>(key+"_X"), f.get<float>(key+"_Y"), f.get<float>(key+"_Width"), f.get<float>(key+"_Height")); |
| 71 | - dets.append(Detection(rect, filePath, isTruth ? -1 : f.get<float>("Confidence", -1), f.get<bool>("Ignore", false), pose)); | 77 | + dets.append(Detection(rect, filePath, isTruth ? -1 : f.get<float>("Confidence", -1), f.get<bool>("Ignore", false), pose, label)); |
| 72 | } | 78 | } |
| 73 | return dets; | 79 | return dets; |
| 74 | } | 80 | } |
| @@ -128,6 +134,27 @@ QMap<QString, Detections> EvalUtils::filterDetections(const QMap<QString, Detect | @@ -128,6 +134,27 @@ QMap<QString, Detections> EvalUtils::filterDetections(const QMap<QString, Detect | ||
| 128 | } | 134 | } |
| 129 | if (!filteredDetections.truth.empty()) allFilteredDetections[key] = filteredDetections; | 135 | if (!filteredDetections.truth.empty()) allFilteredDetections[key] = filteredDetections; |
| 130 | } | 136 | } |
| 137 | + | ||
| 138 | + return allFilteredDetections; | ||
| 139 | +} | ||
| 140 | + | ||
| 141 | +QMap<QString, Detections> EvalUtils::filterLabels(const QMap<QString, Detections> &allDetections, const QString &label) | ||
| 142 | +{ | ||
| 143 | + QMap<QString, Detections> allFilteredDetections; | ||
| 144 | + foreach (QString key, allDetections.keys()) { | ||
| 145 | + Detections detections = allDetections[key]; | ||
| 146 | + Detections filteredDetections; | ||
| 147 | + for (int i = 0; i < detections.predicted.size(); i++) { | ||
| 148 | + if (detections.predicted[i].label == label) | ||
| 149 | + filteredDetections.predicted.append(detections.predicted[i]); | ||
| 150 | + } | ||
| 151 | + for (int i = 0; i < detections.truth.size(); i++) { | ||
| 152 | + if (detections.truth[i].label == label) | ||
| 153 | + filteredDetections.truth.append(detections.truth[i]); | ||
| 154 | + } | ||
| 155 | + if (!filteredDetections.truth.empty()) allFilteredDetections[key] = filteredDetections; | ||
| 156 | + } | ||
| 157 | + | ||
| 131 | return allFilteredDetections; | 158 | return allFilteredDetections; |
| 132 | } | 159 | } |
| 133 | 160 | ||
| @@ -147,6 +174,10 @@ int EvalUtils::associateGroundTruthDetections(QList<ResolvedDetection> &resolved | @@ -147,6 +174,10 @@ int EvalUtils::associateGroundTruthDetections(QList<ResolvedDetection> &resolved | ||
| 147 | for (int p = 0; p < detections.predicted.size(); p++) { | 174 | for (int p = 0; p < detections.predicted.size(); p++) { |
| 148 | Detection predicted = detections.predicted[p]; | 175 | Detection predicted = detections.predicted[p]; |
| 149 | 176 | ||
| 177 | + // Only boxes of the same class can overlap | ||
| 178 | + if (predicted.label != truth.label) | ||
| 179 | + continue; | ||
| 180 | + | ||
| 150 | float predictedWidth = predicted.boundingBox.width(); | 181 | float predictedWidth = predicted.boundingBox.width(); |
| 151 | float x, y, width, height; | 182 | float x, y, width, height; |
| 152 | x = predicted.boundingBox.x() + offsets.x()*predictedWidth; | 183 | x = predicted.boundingBox.x() + offsets.x()*predictedWidth; |
| @@ -175,7 +206,7 @@ int EvalUtils::associateGroundTruthDetections(QList<ResolvedDetection> &resolved | @@ -175,7 +206,7 @@ int EvalUtils::associateGroundTruthDetections(QList<ResolvedDetection> &resolved | ||
| 175 | const Detection predicted = detections.predicted[detection.predicted_idx]; | 206 | const Detection predicted = detections.predicted[detection.predicted_idx]; |
| 176 | 207 | ||
| 177 | if (!truth.ignore) | 208 | if (!truth.ignore) |
| 178 | - resolved.append(ResolvedDetection(predicted.filePath, predicted.boundingBox, predicted.confidence, detection.overlap, truth.boundingBox, truth.pose == predicted.pose)); | 209 | + resolved.append(ResolvedDetection(predicted.filePath, predicted.boundingBox, predicted.confidence, detection.overlap, truth.boundingBox, truth.pose == predicted.pose, truth.label)); |
| 179 | 210 | ||
| 180 | removedTruth.append(detection.truth_idx); | 211 | removedTruth.append(detection.truth_idx); |
| 181 | removedPredicted.append(detection.predicted_idx); | 212 | removedPredicted.append(detection.predicted_idx); |
| @@ -192,11 +223,11 @@ int EvalUtils::associateGroundTruthDetections(QList<ResolvedDetection> &resolved | @@ -192,11 +223,11 @@ int EvalUtils::associateGroundTruthDetections(QList<ResolvedDetection> &resolved | ||
| 192 | 223 | ||
| 193 | // False positive | 224 | // False positive |
| 194 | for (int i = 0; i < detections.predicted.size(); i++) | 225 | for (int i = 0; i < detections.predicted.size(); i++) |
| 195 | - if (!removedPredicted.contains(i)) resolved.append(ResolvedDetection(detections.predicted[i].filePath, detections.predicted[i].boundingBox, detections.predicted[i].confidence, 0, QRectF(), false)); | 226 | + if (!removedPredicted.contains(i)) resolved.append(ResolvedDetection(detections.predicted[i].filePath, detections.predicted[i].boundingBox, detections.predicted[i].confidence, 0, QRectF(), false, detections.predicted[i].label)); |
| 196 | 227 | ||
| 197 | // False negative | 228 | // False negative |
| 198 | for (int i = 0; i < detections.truth.size(); i++) | 229 | for (int i = 0; i < detections.truth.size(); i++) |
| 199 | - if (!removedTruth.contains(i) && !detections.truth[i].ignore) falseNegative.append(ResolvedDetection(detections.truth[i].filePath, detections.truth[i].boundingBox, -std::numeric_limits<float>::max(), 0, QRectF(), false)); | 230 | + if (!removedTruth.contains(i) && !detections.truth[i].ignore) falseNegative.append(ResolvedDetection(detections.truth[i].filePath, detections.truth[i].boundingBox, -std::numeric_limits<float>::max(), 0, QRectF(), false, detections.truth[i].label)); |
| 200 | } | 231 | } |
| 201 | 232 | ||
| 202 | if (offsets.x() == 0) { | 233 | if (offsets.x() == 0) { |
openbr/core/evalutils.h
| @@ -7,7 +7,8 @@ | @@ -7,7 +7,8 @@ | ||
| 7 | 7 | ||
| 8 | namespace EvalUtils | 8 | namespace EvalUtils |
| 9 | { | 9 | { |
| 10 | - struct Detection | 10 | + |
| 11 | +struct Detection | ||
| 11 | { | 12 | { |
| 12 | QRectF boundingBox; | 13 | QRectF boundingBox; |
| 13 | QString filePath; | 14 | QString filePath; |
| @@ -18,14 +19,17 @@ namespace EvalUtils | @@ -18,14 +19,17 @@ namespace EvalUtils | ||
| 18 | // true negative, or false negative, it will simply be ignored. | 19 | // true negative, or false negative, it will simply be ignored. |
| 19 | bool ignore; | 20 | bool ignore; |
| 20 | QString pose; | 21 | QString pose; |
| 22 | + // The label field can be used to distinguish between different object classes | ||
| 23 | + QString label; | ||
| 21 | 24 | ||
| 22 | Detection() {} | 25 | Detection() {} |
| 23 | - Detection(const QRectF &boundingBox, const QString &filePath = QString(), float confidence = -1, bool ignore = false, const QString &pose = "Frontal") : | 26 | + Detection(const QRectF &boundingBox, const QString &filePath = QString(), float confidence = -1, bool ignore = false, const QString &pose = "Frontal", const QString &label = "") : |
| 24 | boundingBox(boundingBox), | 27 | boundingBox(boundingBox), |
| 25 | filePath(filePath), | 28 | filePath(filePath), |
| 26 | confidence(confidence), | 29 | confidence(confidence), |
| 27 | ignore(ignore), | 30 | ignore(ignore), |
| 28 | - pose(pose) | 31 | + pose(pose), |
| 32 | + label(label) | ||
| 29 | {} | 33 | {} |
| 30 | 34 | ||
| 31 | float overlap(const Detection &other) const | 35 | float overlap(const Detection &other) const |
| @@ -50,18 +54,20 @@ struct ResolvedDetection | @@ -50,18 +54,20 @@ struct ResolvedDetection | ||
| 50 | QRectF boundingBox, groundTruthBoundingBox; | 54 | QRectF boundingBox, groundTruthBoundingBox; |
| 51 | float confidence, overlap; | 55 | float confidence, overlap; |
| 52 | bool poseMatch; | 56 | bool poseMatch; |
| 57 | + QString label; | ||
| 53 | ResolvedDetection() : | 58 | ResolvedDetection() : |
| 54 | confidence(-1), | 59 | confidence(-1), |
| 55 | overlap(-1) | 60 | overlap(-1) |
| 56 | {} | 61 | {} |
| 57 | 62 | ||
| 58 | -ResolvedDetection(const QString &filePath, const QRectF &boundingBox, float confidence, float overlap, const QRectF &groundTruthBoundingBox, bool poseMatch) : | 63 | +ResolvedDetection(const QString &filePath, const QRectF &boundingBox, float confidence, float overlap, const QRectF &groundTruthBoundingBox, bool poseMatch, const QString &label) : |
| 59 | filePath(filePath), | 64 | filePath(filePath), |
| 60 | boundingBox(boundingBox), | 65 | boundingBox(boundingBox), |
| 61 | groundTruthBoundingBox(groundTruthBoundingBox), | 66 | groundTruthBoundingBox(groundTruthBoundingBox), |
| 62 | confidence(confidence), | 67 | confidence(confidence), |
| 63 | overlap(overlap), | 68 | overlap(overlap), |
| 64 | - poseMatch(poseMatch) | 69 | + poseMatch(poseMatch), |
| 70 | + label(label) | ||
| 65 | {} | 71 | {} |
| 66 | 72 | ||
| 67 | inline bool operator<(const ResolvedDetection &other) const { return confidence > other.confidence; } | 73 | inline bool operator<(const ResolvedDetection &other) const { return confidence > other.confidence; } |
| @@ -99,6 +105,7 @@ struct DetectionOperatingPoint | @@ -99,6 +105,7 @@ struct DetectionOperatingPoint | ||
| 99 | QList<Detection> getDetections(const DetectionKey &key, const br::File &f, bool isTruth); | 105 | QList<Detection> getDetections(const DetectionKey &key, const br::File &f, bool isTruth); |
| 100 | QMap<QString, Detections> getDetections(const br::File &predictedGallery, const br::File &truthGallery); | 106 | QMap<QString, Detections> getDetections(const br::File &predictedGallery, const br::File &truthGallery); |
| 101 | QMap<QString, Detections> filterDetections(const QMap<QString, Detections> &allDetections, int threshold, bool useMin = true, float relativeThreshold = 0); | 107 | QMap<QString, Detections> filterDetections(const QMap<QString, Detections> &allDetections, int threshold, bool useMin = true, float relativeThreshold = 0); |
| 108 | + QMap<QString, Detections> filterLabels(const QMap<QString, Detections> &allDetections, const QString &label); | ||
| 102 | int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QList<ResolvedDetection> &falseNegative, QMap<QString, Detections> &all, QRectF &offsets); | 109 | int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QList<ResolvedDetection> &falseNegative, QMap<QString, Detections> &all, QRectF &offsets); |
| 103 | QStringList computeDetectionResults(const QList<ResolvedDetection> &detections, int totalTrueDetections, int numImages, bool discrete, QList<DetectionOperatingPoint> &points); | 110 | QStringList computeDetectionResults(const QList<ResolvedDetection> &detections, int totalTrueDetections, int numImages, bool discrete, QList<DetectionOperatingPoint> &points); |
| 104 | inline int getNumberOfImages(const QMap<QString, Detections> detections) | 111 | inline int getNumberOfImages(const QMap<QString, Detections> detections) |
openbr/openbr.cpp
| @@ -126,9 +126,9 @@ void br_eval_clustering(const char *clusters, const char *truth_gallery, const c | @@ -126,9 +126,9 @@ void br_eval_clustering(const char *clusters, const char *truth_gallery, const c | ||
| 126 | EvalClustering(clusters, truth_gallery, truth_property, cluster_csv, cluster_property); | 126 | EvalClustering(clusters, truth_gallery, truth_property, cluster_csv, cluster_property); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | -float br_eval_detection(const char *predicted_gallery, const char *truth_gallery, const char *csv, bool normalize, int minSize, int maxSize, float relativeMinSize) | 129 | +float br_eval_detection(const char *predicted_gallery, const char *truth_gallery, const char *csv, bool normalize, int minSize, int maxSize, float relativeMinSize, const char* label) |
| 130 | { | 130 | { |
| 131 | - return EvalDetection(predicted_gallery, truth_gallery, csv, normalize, minSize, maxSize, relativeMinSize); | 131 | + return EvalDetection(predicted_gallery, truth_gallery, csv, normalize, minSize, maxSize, relativeMinSize, label); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | float br_eval_landmarking(const char *predicted_gallery, const char *truth_gallery, const char *csv, int normalization_index_a, int normalization_index_b, int sample_index, int total_examples) | 134 | float br_eval_landmarking(const char *predicted_gallery, const char *truth_gallery, const char *csv, int normalization_index_a, int normalization_index_b, int sample_index, int total_examples) |
openbr/openbr.h
| @@ -58,7 +58,7 @@ BR_EXPORT void br_eval_classification(const char *predicted_gallery, const char | @@ -58,7 +58,7 @@ BR_EXPORT void br_eval_classification(const char *predicted_gallery, const char | ||
| 58 | 58 | ||
| 59 | BR_EXPORT void br_eval_clustering(const char *clusters, const char *truth_gallery, const char *truth_property = "", bool cluster_csv = true, const char *cluster_property = ""); | 59 | BR_EXPORT void br_eval_clustering(const char *clusters, const char *truth_gallery, const char *truth_property = "", bool cluster_csv = true, const char *cluster_property = ""); |
| 60 | 60 | ||
| 61 | -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, float relativeMinSize = 0); | 61 | +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, float relativeMinSize = 0, const char* label = ""); |
| 62 | 62 | ||
| 63 | BR_EXPORT float br_eval_landmarking(const char *predicted_gallery, const char *truth_gallery, const char *csv = "", int normalization_index_a = 0, int normalization_index_b = 1, int sample_index = 0, int total_examples = 5); | 63 | BR_EXPORT float br_eval_landmarking(const char *predicted_gallery, const char *truth_gallery, const char *csv = "", int normalization_index_a = 0, int normalization_index_b = 1, int sample_index = 0, int total_examples = 5); |
| 64 | 64 |