Commit 9a0c009f7b9e8028ceca13dddd988a63f8e8285d
1 parent
9633db66
add -plotKNN
Showing
8 changed files
with
81 additions
and
22 deletions
app/br/br.cpp
| @@ -169,8 +169,8 @@ public: | @@ -169,8 +169,8 @@ public: | ||
| 169 | check(parc >= 2 && parc <= 4, "Incorrect parameter count for 'evalRegression'."); | 169 | check(parc >= 2 && parc <= 4, "Incorrect parameter count for 'evalRegression'."); |
| 170 | br_eval_regression(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? parv[3] : ""); | 170 | br_eval_regression(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? parv[3] : ""); |
| 171 | } else if (!strcmp(fun, "evalKNN")) { | 171 | } else if (!strcmp(fun, "evalKNN")) { |
| 172 | - check(parc == 3, "Incorrect parameter count for 'evalKNN'."); | ||
| 173 | - br_eval_knn(parv[0], parv[1], parv[2]); | 172 | + check(parc >= 2 && parc <= 3, "Incorrect parameter count for 'evalKNN'."); |
| 173 | + br_eval_knn(parv[0], parv[1], parc > 2 ? parv[2] : ""); | ||
| 174 | } else if (!strcmp(fun, "pairwiseCompare")) { | 174 | } else if (!strcmp(fun, "pairwiseCompare")) { |
| 175 | check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'pairwiseCompare'."); | 175 | check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'pairwiseCompare'."); |
| 176 | br_pairwise_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); | 176 | br_pairwise_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); |
| @@ -186,6 +186,9 @@ public: | @@ -186,6 +186,9 @@ public: | ||
| 186 | } else if (!strcmp(fun, "plotMetadata")) { | 186 | } else if (!strcmp(fun, "plotMetadata")) { |
| 187 | check(parc >= 2, "Incorrect parameter count for 'plotMetadata'."); | 187 | check(parc >= 2, "Incorrect parameter count for 'plotMetadata'."); |
| 188 | br_plot_metadata(parc-1, parv, parv[parc-1], true); | 188 | br_plot_metadata(parc-1, parv, parv[parc-1], true); |
| 189 | + } else if (!strcmp(fun, "plotKNN")) { | ||
| 190 | + check(parc >=2, "Incorrect parameter count for 'plotKNN'."); | ||
| 191 | + br_plot_knn(parc-1, parv, parv[parc-1], true); | ||
| 189 | } else if (!strcmp(fun, "project")) { | 192 | } else if (!strcmp(fun, "project")) { |
| 190 | check(parc == 2, "Insufficient parameter count for 'project'."); | 193 | check(parc == 2, "Insufficient parameter count for 'project'."); |
| 191 | br_project(parv[0], parv[1]); | 194 | br_project(parv[0], parv[1]); |
| @@ -279,13 +282,14 @@ private: | @@ -279,13 +282,14 @@ private: | ||
| 279 | "-evalDetection <predicted_gallery> <truth_gallery> [{csv}] [{normalize}] [{minSize}] [{maxSize}]\n" | 282 | "-evalDetection <predicted_gallery> <truth_gallery> [{csv}] [{normalize}] [{minSize}] [{maxSize}]\n" |
| 280 | "-evalLandmarking <predicted_gallery> <truth_gallery> [{csv} [<normalization_index_a> <normalization_index_b>] [sample_index] [total_examples]]\n" | 283 | "-evalLandmarking <predicted_gallery> <truth_gallery> [{csv} [<normalization_index_a> <normalization_index_b>] [sample_index] [total_examples]]\n" |
| 281 | "-evalRegression <predicted_gallery> <truth_gallery> <predicted property name> <ground truth property name>\n" | 284 | "-evalRegression <predicted_gallery> <truth_gallery> <predicted property name> <ground truth property name>\n" |
| 282 | - "-evalKNN <knn_graph> <knn_truth> [{iet_file}]\n" | 285 | + "-evalKNN <knn_graph> <knn_truth> [{csv}]\n" |
| 283 | "-pairwiseCompare <target_gallery> <query_gallery> [{output}]\n" | 286 | "-pairwiseCompare <target_gallery> <query_gallery> [{output}]\n" |
| 284 | "-inplaceEval <simmat> <target> <query> [{csv}]\n" | 287 | "-inplaceEval <simmat> <target> <query> [{csv}]\n" |
| 285 | "-assertEval <simmat> <mask> <accuracy>\n" | 288 | "-assertEval <simmat> <mask> <accuracy>\n" |
| 286 | "-plotDetection <file> ... <file> {destination}\n" | 289 | "-plotDetection <file> ... <file> {destination}\n" |
| 287 | "-plotLandmarking <file> ... <file> {destination}\n" | 290 | "-plotLandmarking <file> ... <file> {destination}\n" |
| 288 | "-plotMetadata <file> ... <file> <columns>\n" | 291 | "-plotMetadata <file> ... <file> <columns>\n" |
| 292 | + "-plotKNN <file> ... <file> {destination}\n" | ||
| 289 | "-project <input_gallery> {output_gallery}\n" | 293 | "-project <input_gallery> {output_gallery}\n" |
| 290 | "-deduplicate <input_gallery> <output_gallery> <threshold>\n" | 294 | "-deduplicate <input_gallery> <output_gallery> <threshold>\n" |
| 291 | "-likely <input_type> <output_type> <output_likely_source>\n" | 295 | "-likely <input_type> <output_type> <output_likely_source>\n" |
openbr/core/eval.cpp
| @@ -1336,7 +1336,7 @@ void readKNNTruth(size_t probeCount, QVector< QList<size_t> > &groundTruth, cons | @@ -1336,7 +1336,7 @@ void readKNNTruth(size_t probeCount, QVector< QList<size_t> > &groundTruth, cons | ||
| 1336 | qFatal("Invalid ground truth file!"); | 1336 | qFatal("Invalid ground truth file!"); |
| 1337 | } | 1337 | } |
| 1338 | 1338 | ||
| 1339 | -void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &iet) | 1339 | +void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &csv) |
| 1340 | { | 1340 | { |
| 1341 | qDebug("Evaluating k-NN of %s against %s", qPrintable(knnGraph), qPrintable(knnTruth)); | 1341 | qDebug("Evaluating k-NN of %s against %s", qPrintable(knnGraph), qPrintable(knnTruth)); |
| 1342 | 1342 | ||
| @@ -1406,19 +1406,14 @@ void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &ie | @@ -1406,19 +1406,14 @@ void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &ie | ||
| 1406 | if (numUnmatedSearches == 0) | 1406 | if (numUnmatedSearches == 0) |
| 1407 | qFatal("No unmated searches!"); | 1407 | qFatal("No unmated searches!"); |
| 1408 | 1408 | ||
| 1409 | - printf("Rank-%i Return Rate: %g\n", 1, getCMC(firstGenuineReturns, 1, numMatedSearches)); | 1409 | + |
| 1410 | + qDebug("Rank-%d Return Rate: %.3f", 1, getCMC(firstGenuineReturns, 1, numMatedSearches)); | ||
| 1410 | if (k >=5) | 1411 | if (k >=5) |
| 1411 | - printf("Rank-%i Return Rate: %g\n", 5, getCMC(firstGenuineReturns, 5, numMatedSearches)); | 1412 | + qDebug("Rank-%d Return Rate: %.3f", 5, getCMC(firstGenuineReturns, 5, numMatedSearches)); |
| 1412 | if (k >=10) | 1413 | if (k >=10) |
| 1413 | - printf("Rank-%i Return Rate: %g\n", 10, getCMC(firstGenuineReturns, 10, numMatedSearches)); | ||
| 1414 | - | ||
| 1415 | - printf("Rank-%zu Return Rate: %g\n", k, double(numMatedSimilarities) / double(numMatedSearches)); | 1414 | + qDebug("Rank-%d Return Rate: %.3f", 10, getCMC(firstGenuineReturns, 10, numMatedSearches)); |
| 1416 | 1415 | ||
| 1417 | - // Open the output file | ||
| 1418 | - QFile ietFile(iet); | ||
| 1419 | - if (!ietFile.open(QFile::WriteOnly | QFile::Text)) | ||
| 1420 | - qFatal("Failed to open IET file for writing!"); | ||
| 1421 | - ietFile.write("Threshold,FPIR,FNIR\n"); | 1416 | + qDebug("Rank-%zu Return Rate: %.3f", k, double(numMatedSimilarities) / double(numMatedSearches)); |
| 1422 | 1417 | ||
| 1423 | /* | 1418 | /* |
| 1424 | * Iterate through the similarity scores highest-to-lowest, | 1419 | * Iterate through the similarity scores highest-to-lowest, |
| @@ -1447,10 +1442,28 @@ void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &ie | @@ -1447,10 +1442,28 @@ void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &ie | ||
| 1447 | } | 1442 | } |
| 1448 | } | 1443 | } |
| 1449 | 1444 | ||
| 1450 | - foreach(const OperatingPoint &operatingPoint, operatingPoints) | ||
| 1451 | - ietFile.write(qPrintable(QString::number(operatingPoint.score) + "," + | ||
| 1452 | - QString::number(operatingPoint.FAR) + "," + | ||
| 1453 | - QString::number(operatingPoint.TAR) + "\n")); | 1445 | + if (!csv.isEmpty()) { |
| 1446 | + // Open the output file | ||
| 1447 | + QFile ietFile(csv); | ||
| 1448 | + if (!ietFile.open(QFile::WriteOnly | QFile::Text)) | ||
| 1449 | + qFatal("Failed to open IET file for writing!"); | ||
| 1450 | + ietFile.write("Plot,X,Y,Z\n"); | ||
| 1451 | + // Write CMC | ||
| 1452 | + const int Max_Retrieval = min(200, (int)k); | ||
| 1453 | + for (int i=1; i<=Max_Retrieval; i++) { | ||
| 1454 | + const float retrievalRate = getCMC(firstGenuineReturns, i, numMatedSearches); | ||
| 1455 | + ietFile.write(qPrintable(QString("CMC,%1,%2,0\n").arg(QString::number(i), QString::number(retrievalRate)))); | ||
| 1456 | + } | ||
| 1457 | + | ||
| 1458 | + foreach(const OperatingPoint &operatingPoint, operatingPoints) | ||
| 1459 | + ietFile.write(qPrintable("IET," + | ||
| 1460 | + QString::number(operatingPoint.FAR) + "," + | ||
| 1461 | + QString::number(operatingPoint.TAR) + "," + | ||
| 1462 | + QString::number(operatingPoint.score) + "\n")); | ||
| 1463 | + } | ||
| 1464 | + | ||
| 1465 | + qDebug("FNIR @ FPIR = 0.1: %.3f", 1-getOperatingPointGivenFAR(operatingPoints, 0.1).TAR); | ||
| 1466 | + qDebug("FNIR @ FPIR = 0.01: %.3f", 1-getOperatingPointGivenFAR(operatingPoints, 0.01).TAR); | ||
| 1454 | } | 1467 | } |
| 1455 | 1468 | ||
| 1456 | } // namespace br | 1469 | } // namespace br |
openbr/core/eval.h
| @@ -33,7 +33,7 @@ namespace br | @@ -33,7 +33,7 @@ namespace br | ||
| 33 | float EvalDetection(const QString &predictedGallery, const QString &truthGallery, const QString &csv = "", bool normalize = false, int minSize = 0, int maxSize = 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, 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 &iet); | 36 | + void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &csv = ""); |
| 37 | 37 | ||
| 38 | struct Candidate | 38 | struct Candidate |
| 39 | { | 39 | { |
openbr/core/plot.cpp
| @@ -346,4 +346,32 @@ bool PlotMetadata(const QStringList &files, const QString &columns, bool show) | @@ -346,4 +346,32 @@ bool PlotMetadata(const QStringList &files, const QString &columns, bool show) | ||
| 346 | return p.finalize(show); | 346 | return p.finalize(show); |
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | +bool PlotKNN(const QStringList &files, const File &destination, bool show) | ||
| 350 | +{ | ||
| 351 | + qDebug("Plotting %d k-NN file(s) to %s", files.size(), qPrintable(destination)); | ||
| 352 | + RPlot p(files, destination); | ||
| 353 | + p.file.write("\nformatData(type=\"knn\")\n\n"); | ||
| 354 | + | ||
| 355 | + QMap<QString,File> optMap; | ||
| 356 | + optMap.insert("rocOptions", File(QString("[xTitle=False Positive Identification Rate (FPIR),yTitle=True Positive Identification Rate (TPIR),xLog=true,yLog=false]"))); | ||
| 357 | + optMap.insert("ietOptions", File(QString("[xTitle=False Positive Identification Rate (FPIR),yTitle=False Negative Identification Rate (FNIR),xLog=true,yLog=true]"))); | ||
| 358 | + optMap.insert("cmcOptions", File(QString("[xTitle=Rank,yTitle=Retrieval Rate,xLog=true,yLog=false,size=1,xLabels=(1,5,10,50,100),xBreaks=(1,5,10,50,100)]"))); | ||
| 359 | + | ||
| 360 | + foreach (const QString &key, optMap.keys()) { | ||
| 361 | + const QStringList options = destination.get<QStringList>(key, QStringList()); | ||
| 362 | + foreach (const QString &option, options) { | ||
| 363 | + QStringList words = QtUtils::parse(option, '='); | ||
| 364 | + QtUtils::checkArgsSize(words[0], words, 1, 2); | ||
| 365 | + optMap[key].set(words[0], words[1]); | ||
| 366 | + } | ||
| 367 | + } | ||
| 368 | + | ||
| 369 | + QString plot = "plot <- plotLine(lineData=%1, options=list(%2), flipY=%3)\nplot\n"; | ||
| 370 | + p.file.write(qPrintable(QString(plot).arg("IET", toRList(optMap["rocOptions"]), "TRUE"))); | ||
| 371 | + p.file.write(qPrintable(QString(plot).arg("IET", toRList(optMap["ietOptions"]), "FALSE"))); | ||
| 372 | + p.file.write(qPrintable(QString(plot).arg("CMC", toRList(optMap["cmcOptions"]), "FALSE"))); | ||
| 373 | + | ||
| 374 | + return p.finalize(show); | ||
| 375 | +} | ||
| 376 | + | ||
| 349 | } // namespace br | 377 | } // namespace br |
openbr/core/plot.h
| @@ -28,6 +28,7 @@ namespace br | @@ -28,6 +28,7 @@ namespace br | ||
| 28 | bool PlotDetection(const QStringList &files, const File &destination, bool show = false); | 28 | bool PlotDetection(const QStringList &files, const File &destination, bool show = false); |
| 29 | bool PlotLandmarking(const QStringList &files, const File &destination, bool show = false); | 29 | bool PlotLandmarking(const QStringList &files, const File &destination, bool show = false); |
| 30 | bool PlotMetadata(const QStringList &files, const QString &destination, bool show = false); | 30 | bool PlotMetadata(const QStringList &files, const QString &destination, bool show = false); |
| 31 | + bool PlotKNN(const QStringList &files, const File &destination, bool show = false); | ||
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | #endif // BR_PLOT_H | 34 | #endif // BR_PLOT_H |
openbr/openbr.cpp
| @@ -145,9 +145,9 @@ void br_eval_regression(const char *predicted_gallery, const char *truth_gallery | @@ -145,9 +145,9 @@ void br_eval_regression(const char *predicted_gallery, const char *truth_gallery | ||
| 145 | EvalRegression(predicted_gallery, truth_gallery, predicted_property, truth_property); | 145 | EvalRegression(predicted_gallery, truth_gallery, predicted_property, truth_property); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | -void br_eval_knn(const char *knnGraph, const char *knnTruth, const char *iet) | 148 | +void br_eval_knn(const char *knnGraph, const char *knnTruth, const char *csv) |
| 149 | { | 149 | { |
| 150 | - EvalKNN(knnGraph, knnTruth, iet); | 150 | + EvalKNN(knnGraph, knnTruth, csv); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | void br_finalize() | 153 | void br_finalize() |
| @@ -221,6 +221,11 @@ bool br_plot_metadata(int num_files, const char *files[], const char *columns, b | @@ -221,6 +221,11 @@ bool br_plot_metadata(int num_files, const char *files[], const char *columns, b | ||
| 221 | return PlotMetadata(QtUtils::toStringList(num_files, files), columns, show); | 221 | return PlotMetadata(QtUtils::toStringList(num_files, files), columns, show); |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | +bool br_plot_knn(int num_files, const char *files[], const char *destination, bool show) | ||
| 225 | +{ | ||
| 226 | + return PlotKNN(QtUtils::toStringList(num_files, files), destination, show); | ||
| 227 | +} | ||
| 228 | + | ||
| 224 | float br_progress() | 229 | float br_progress() |
| 225 | { | 230 | { |
| 226 | return Globals->progress(); | 231 | return Globals->progress(); |
openbr/openbr.h
| @@ -64,7 +64,7 @@ BR_EXPORT float br_eval_landmarking(const char *predicted_gallery, const char *t | @@ -64,7 +64,7 @@ BR_EXPORT float br_eval_landmarking(const char *predicted_gallery, const char *t | ||
| 64 | 64 | ||
| 65 | BR_EXPORT void br_eval_regression(const char *predicted_gallery, const char *truth_gallery, const char *predicted_property = "", const char *truth_property = ""); | 65 | BR_EXPORT void br_eval_regression(const char *predicted_gallery, const char *truth_gallery, const char *predicted_property = "", const char *truth_property = ""); |
| 66 | 66 | ||
| 67 | -BR_EXPORT void br_eval_knn(const char *knnGraph, const char *knnTruth, const char *iet); | 67 | +BR_EXPORT void br_eval_knn(const char *knnGraph, const char *knnTruth, const char *csv = ""); |
| 68 | 68 | ||
| 69 | BR_EXPORT void br_finalize(); | 69 | BR_EXPORT void br_finalize(); |
| 70 | 70 | ||
| @@ -93,6 +93,8 @@ BR_EXPORT bool br_plot_landmarking(int num_files, const char *files[], const cha | @@ -93,6 +93,8 @@ BR_EXPORT bool br_plot_landmarking(int num_files, const char *files[], const cha | ||
| 93 | 93 | ||
| 94 | BR_EXPORT bool br_plot_metadata(int num_files, const char *files[], const char *columns, bool show = false); | 94 | BR_EXPORT bool br_plot_metadata(int num_files, const char *files[], const char *columns, bool show = false); |
| 95 | 95 | ||
| 96 | +BR_EXPORT bool br_plot_knn(int num_files, const char *files[], const char *destination, bool show = false); | ||
| 97 | + | ||
| 96 | BR_EXPORT float br_progress(); | 98 | BR_EXPORT float br_progress(); |
| 97 | 99 | ||
| 98 | BR_EXPORT void br_read_pipe(const char *pipe, int *argc, char ***argv); | 100 | BR_EXPORT void br_read_pipe(const char *pipe, int *argc, char ***argv); |
share/openbr/plotting/plot_utils.R
| @@ -217,6 +217,12 @@ formatData <- function(type="eval") { | @@ -217,6 +217,12 @@ formatData <- function(type="eval") { | ||
| 217 | NormLength <<- data[grep("NormLength",data$Plot),-c(1)] | 217 | NormLength <<- data[grep("NormLength",data$Plot),-c(1)] |
| 218 | sample <<- readImageData(Sample) | 218 | sample <<- readImageData(Sample) |
| 219 | rows <<- sample[[1]]$value | 219 | rows <<- sample[[1]]$value |
| 220 | + } else if (type == "knn") { | ||
| 221 | + # Split data into individual plots | ||
| 222 | + IET <<- data[grep("IET",data$Plot),-c(1)] | ||
| 223 | + IET$Y <<- as.numeric(as.character(IET$Y)) | ||
| 224 | + CMC <<- data[grep("CMC",data$Plot),-c(1)] | ||
| 225 | + CMC$Y <<- as.numeric(as.character(CMC$Y)) | ||
| 220 | } | 226 | } |
| 221 | } | 227 | } |
| 222 | 228 |