Commit 19a31ceddcf712c3edf952a4177634ca41e2742e
1 parent
74762655
Plot now uses 'False Accepts per Image' as x-axis parameter
Showing
2 changed files
with
20 additions
and
9 deletions
openbr/core/eval.cpp
100644 → 100755
| @@ -607,11 +607,11 @@ struct DetectionOperatingPoint | @@ -607,11 +607,11 @@ struct DetectionOperatingPoint | ||
| 607 | { | 607 | { |
| 608 | float Recall, FalsePositiveRate, Precision; | 608 | float Recall, FalsePositiveRate, Precision; |
| 609 | DetectionOperatingPoint() : Recall(-1), FalsePositiveRate(-1), Precision(-1) {} | 609 | DetectionOperatingPoint() : Recall(-1), FalsePositiveRate(-1), Precision(-1) {} |
| 610 | - DetectionOperatingPoint(float TP, float FP, float totalPositives) | ||
| 611 | - : Recall(TP/totalPositives), FalsePositiveRate(FP/totalPositives), Precision(TP/(TP+FP)) {} | 610 | + DetectionOperatingPoint(float TP, float FP, float totalPositives, float numImages) |
| 611 | + : Recall(TP/totalPositives), FalsePositiveRate(FP/numImages), Precision(TP/(TP+FP)) {} | ||
| 612 | }; | 612 | }; |
| 613 | 613 | ||
| 614 | -static QStringList computeDetectionResults(const QList<ResolvedDetection> &detections, int totalTrueDetections, bool discrete) | 614 | +static QStringList computeDetectionResults(const QList<ResolvedDetection> &detections, int totalTrueDetections, int numImages, bool discrete) |
| 615 | { | 615 | { |
| 616 | QList<DetectionOperatingPoint> points; | 616 | QList<DetectionOperatingPoint> points; |
| 617 | float TP = 0, FP = 0, prevFP = -1; | 617 | float TP = 0, FP = 0, prevFP = -1; |
| @@ -627,7 +627,7 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec | @@ -627,7 +627,7 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec | ||
| 627 | } | 627 | } |
| 628 | if ((i == detections.size()-1) || (detection.confidence > detections[i+1].confidence)) { | 628 | if ((i == detections.size()-1) || (detection.confidence > detections[i+1].confidence)) { |
| 629 | if (FP > prevFP || (i == detections.size()-1)) { | 629 | if (FP > prevFP || (i == detections.size()-1)) { |
| 630 | - points.append(DetectionOperatingPoint(TP, FP, totalTrueDetections)); | 630 | + points.append(DetectionOperatingPoint(TP, FP, totalTrueDetections, numImages)); |
| 631 | prevFP = FP; | 631 | prevFP = FP; |
| 632 | } | 632 | } |
| 633 | } | 633 | } |
| @@ -745,6 +745,17 @@ static QMap<QString, Detections> getDetections(const File &predictedGallery, con | @@ -745,6 +745,17 @@ static QMap<QString, Detections> getDetections(const File &predictedGallery, con | ||
| 745 | return allDetections; | 745 | return allDetections; |
| 746 | } | 746 | } |
| 747 | 747 | ||
| 748 | +static int getNumberOfImages(const File &truthGallery) | ||
| 749 | +{ | ||
| 750 | + const FileList files = TemplateList::fromGallery(truthGallery).files(); | ||
| 751 | + | ||
| 752 | + QStringList names; | ||
| 753 | + foreach(const File file, files) | ||
| 754 | + if (!names.contains(file.fileName())) | ||
| 755 | + names.append(file.fileName()); | ||
| 756 | + return names.size(); | ||
| 757 | +} | ||
| 758 | + | ||
| 748 | static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QList<ResolvedDetection> &falseNegative, QMap<QString, Detections> &all, QRectF &offsets) | 759 | static int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QList<ResolvedDetection> &falseNegative, QMap<QString, Detections> &all, QRectF &offsets) |
| 749 | { | 760 | { |
| 750 | float dLeftTotal = 0.0, dRightTotal = 0.0, dTopTotal = 0.0, dBottomTotal = 0.0; | 761 | float dLeftTotal = 0.0, dRightTotal = 0.0, dTopTotal = 0.0, dBottomTotal = 0.0; |
| @@ -864,8 +875,8 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | @@ -864,8 +875,8 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery | ||
| 864 | std::sort(resolvedDetections.begin(), resolvedDetections.end()); | 875 | std::sort(resolvedDetections.begin(), resolvedDetections.end()); |
| 865 | QStringList lines; | 876 | QStringList lines; |
| 866 | lines.append("Plot, X, Y"); | 877 | lines.append("Plot, X, Y"); |
| 867 | - lines.append(computeDetectionResults(resolvedDetections, totalTrueDetections, true)); | ||
| 868 | - lines.append(computeDetectionResults(resolvedDetections, totalTrueDetections, false)); | 878 | + lines.append(computeDetectionResults(resolvedDetections, totalTrueDetections, getNumberOfImages(truthGallery), true)); |
| 879 | + lines.append(computeDetectionResults(resolvedDetections, totalTrueDetections, getNumberOfImages(truthGallery), false)); | ||
| 869 | 880 | ||
| 870 | float averageOverlap; | 881 | float averageOverlap; |
| 871 | { // Overlap Density | 882 | { // Overlap Density |
openbr/core/plot.cpp
| @@ -350,10 +350,10 @@ bool PlotDetection(const QStringList &files, const File &destination, bool show) | @@ -350,10 +350,10 @@ bool PlotDetection(const QStringList &files, const File &destination, bool show) | ||
| 350 | p.file.write(qPrintable(QString("qplot(X, Y, data=%1ROC%2").arg(type, (p.major.smooth || p.minor.smooth) ? ", geom=\"smooth\", method=loess, level=0.99" : QString(", geom=\"%1\"").arg(plotType)) + | 350 | p.file.write(qPrintable(QString("qplot(X, Y, data=%1ROC%2").arg(type, (p.major.smooth || p.minor.smooth) ? ", geom=\"smooth\", method=loess, level=0.99" : QString(", geom=\"%1\"").arg(plotType)) + |
| 351 | (p.major.size > 1 ? QString(", colour=factor(%1)").arg(p.major.header) : QString()) + | 351 | (p.major.size > 1 ? QString(", colour=factor(%1)").arg(p.major.header) : QString()) + |
| 352 | (p.minor.size > 1 ? QString(", linetype=factor(%1)").arg(p.minor.header) : QString()) + | 352 | (p.minor.size > 1 ? QString(", linetype=factor(%1)").arg(p.minor.header) : QString()) + |
| 353 | - QString(", xlab=\"Percentage of False Accepts Per Image\", ylab=\"True Accept Rate\") + theme_minimal()") + | 353 | + QString(", xlab=\"False Accepts Per Image\", ylab=\"True Accept Rate\") + theme_minimal()") + |
| 354 | (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + | 354 | (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + |
| 355 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + | 355 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + |
| 356 | - QString(" + scale_x_log10(labels=percent) + scale_y_continuous(labels=percent, limits=c(0,1)) + annotation_logticks(sides=\"b\") + ggtitle(\"%1\") + theme(legend.position=\"bottom\")\n\n").arg(type))); | 356 | + QString(" + scale_x_log10() + scale_y_continuous(labels=percent, limits=c(0,1)) + annotation_logticks(sides=\"b\") + ggtitle(\"%1\") + theme(legend.position=\"bottom\")\n\n").arg(type))); |
| 357 | 357 | ||
| 358 | foreach (const QString &type, QStringList() << "Discrete" << "Continuous") | 358 | foreach (const QString &type, QStringList() << "Discrete" << "Continuous") |
| 359 | p.file.write(qPrintable(QString("qplot(X, Y, data=%1PR%2").arg(type, (p.major.smooth || p.minor.smooth) ? ", geom=\"smooth\", method=loess, level=0.99" : QString(", geom=\"%1\"").arg(plotType)) + | 359 | p.file.write(qPrintable(QString("qplot(X, Y, data=%1PR%2").arg(type, (p.major.smooth || p.minor.smooth) ? ", geom=\"smooth\", method=loess, level=0.99" : QString(", geom=\"%1\"").arg(plotType)) + |
| @@ -362,7 +362,7 @@ bool PlotDetection(const QStringList &files, const File &destination, bool show) | @@ -362,7 +362,7 @@ bool PlotDetection(const QStringList &files, const File &destination, bool show) | ||
| 362 | QString(", xlab=\"Recall\", ylab=\"Precision\") + theme_minimal()") + | 362 | QString(", xlab=\"Recall\", ylab=\"Precision\") + theme_minimal()") + |
| 363 | (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + | 363 | (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + |
| 364 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + | 364 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + |
| 365 | - QString(" + scale_x_continuous(labels=percent, limits=c(0,1)) + scale_y_continuous(labels=percent, limits=c(0,1)) + ggtitle(\"%1\") + theme(legend.position=\"bottom\")\n\n").arg(type))); | 365 | + QString(" + scale_x_continuous(limits=c(0,1)) + scale_y_continuous(labels=percent, limits=c(0,1)) + ggtitle(\"%1\") + theme(legend.position=\"bottom\")\n\n").arg(type))); |
| 366 | 366 | ||
| 367 | p.file.write(qPrintable(QString("qplot(X, data=Overlap, geom=\"histogram\", position=\"identity\", xlab=\"Overlap\", ylab=\"Frequency\")") + | 367 | p.file.write(qPrintable(QString("qplot(X, data=Overlap, geom=\"histogram\", position=\"identity\", xlab=\"Overlap\", ylab=\"Frequency\")") + |
| 368 | QString(" + theme_minimal() + scale_x_continuous(minor_breaks=NULL) + scale_y_continuous(minor_breaks=NULL) + theme(axis.text.y=element_blank(), axis.ticks=element_blank(), axis.text.x=element_text(angle=-90, hjust=0))") + | 368 | QString(" + theme_minimal() + scale_x_continuous(minor_breaks=NULL) + scale_y_continuous(minor_breaks=NULL) + theme(axis.text.y=element_blank(), axis.ticks=element_blank(), axis.text.x=element_text(angle=-90, hjust=0))") + |