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 | 169 | check(parc >= 2 && parc <= 4, "Incorrect parameter count for 'evalRegression'."); |
| 170 | 170 | br_eval_regression(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? parv[3] : ""); |
| 171 | 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 | 174 | } else if (!strcmp(fun, "pairwiseCompare")) { |
| 175 | 175 | check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'pairwiseCompare'."); |
| 176 | 176 | br_pairwise_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); |
| ... | ... | @@ -186,6 +186,9 @@ public: |
| 186 | 186 | } else if (!strcmp(fun, "plotMetadata")) { |
| 187 | 187 | check(parc >= 2, "Incorrect parameter count for 'plotMetadata'."); |
| 188 | 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 | 192 | } else if (!strcmp(fun, "project")) { |
| 190 | 193 | check(parc == 2, "Insufficient parameter count for 'project'."); |
| 191 | 194 | br_project(parv[0], parv[1]); |
| ... | ... | @@ -279,13 +282,14 @@ private: |
| 279 | 282 | "-evalDetection <predicted_gallery> <truth_gallery> [{csv}] [{normalize}] [{minSize}] [{maxSize}]\n" |
| 280 | 283 | "-evalLandmarking <predicted_gallery> <truth_gallery> [{csv} [<normalization_index_a> <normalization_index_b>] [sample_index] [total_examples]]\n" |
| 281 | 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 | 286 | "-pairwiseCompare <target_gallery> <query_gallery> [{output}]\n" |
| 284 | 287 | "-inplaceEval <simmat> <target> <query> [{csv}]\n" |
| 285 | 288 | "-assertEval <simmat> <mask> <accuracy>\n" |
| 286 | 289 | "-plotDetection <file> ... <file> {destination}\n" |
| 287 | 290 | "-plotLandmarking <file> ... <file> {destination}\n" |
| 288 | 291 | "-plotMetadata <file> ... <file> <columns>\n" |
| 292 | + "-plotKNN <file> ... <file> {destination}\n" | |
| 289 | 293 | "-project <input_gallery> {output_gallery}\n" |
| 290 | 294 | "-deduplicate <input_gallery> <output_gallery> <threshold>\n" |
| 291 | 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 | 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 | 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 | 1406 | if (numUnmatedSearches == 0) |
| 1407 | 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 | 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 | 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 | 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 | 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 | 1469 | } // namespace br | ... | ... |
openbr/core/eval.h
| ... | ... | @@ -33,7 +33,7 @@ namespace br |
| 33 | 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 | 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 | 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 | 38 | struct Candidate |
| 39 | 39 | { | ... | ... |
openbr/core/plot.cpp
| ... | ... | @@ -346,4 +346,32 @@ bool PlotMetadata(const QStringList &files, const QString &columns, bool show) |
| 346 | 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 | 377 | } // namespace br | ... | ... |
openbr/core/plot.h
| ... | ... | @@ -28,6 +28,7 @@ namespace br |
| 28 | 28 | bool PlotDetection(const QStringList &files, const File &destination, bool show = false); |
| 29 | 29 | bool PlotLandmarking(const QStringList &files, const File &destination, bool show = false); |
| 30 | 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 | 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 | 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 | 153 | void br_finalize() |
| ... | ... | @@ -221,6 +221,11 @@ bool br_plot_metadata(int num_files, const char *files[], const char *columns, b |
| 221 | 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 | 229 | float br_progress() |
| 225 | 230 | { |
| 226 | 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 | 64 | |
| 65 | 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 | 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 | 93 | |
| 94 | 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 | 98 | BR_EXPORT float br_progress(); |
| 97 | 99 | |
| 98 | 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 | 217 | NormLength <<- data[grep("NormLength",data$Plot),-c(1)] |
| 218 | 218 | sample <<- readImageData(Sample) |
| 219 | 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 | ... | ... |