Commit 9a0c009f7b9e8028ceca13dddd988a63f8e8285d

Authored by bhklein
1 parent 9633db66

add -plotKNN

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&lt; QList&lt;size_t&gt; &gt; &amp;groundTruth, cons @@ -1336,7 +1336,7 @@ void readKNNTruth(size_t probeCount, QVector&lt; QList&lt;size_t&gt; &gt; &amp;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 &amp;knnGraph, const QString &amp;knnTruth, const QString &amp;ie @@ -1406,19 +1406,14 @@ void EvalKNN(const QString &amp;knnGraph, const QString &amp;knnTruth, const QString &amp;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 &amp;knnGraph, const QString &amp;knnTruth, const QString &amp;ie @@ -1447,10 +1442,28 @@ void EvalKNN(const QString &amp;knnGraph, const QString &amp;knnTruth, const QString &amp;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 &amp;files, const QString &amp;columns, bool show) @@ -346,4 +346,32 @@ bool PlotMetadata(const QStringList &amp;files, const QString &amp;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 &lt;- function(type=&quot;eval&quot;) { @@ -217,6 +217,12 @@ formatData &lt;- function(type=&quot;eval&quot;) {
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