Commit 84b41a656d4380e7bd37e99399ba7c8f11518394

Authored by Josh Klontz
1 parent 2fe3c0ea

added -eval shortcut

app/br/br.cpp
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 #include <stdio.h> 20 #include <stdio.h>
21 #include <stdlib.h> 21 #include <stdlib.h>
22 #include <string.h> 22 #include <string.h>
23 -#include <openbr/openbr.h> 23 +#include <openbr/openbr_plugin.h>
24 24
25 /*! 25 /*!
26 * \defgroup cli Command Line Interface 26 * \defgroup cli Command Line Interface
@@ -95,8 +95,15 @@ public: @@ -95,8 +95,15 @@ public:
95 check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'compare'."); 95 check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'compare'.");
96 br_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); 96 br_compare(parv[0], parv[1], parc == 3 ? parv[2] : "");
97 } else if (!strcmp(fun, "eval")) { 97 } else if (!strcmp(fun, "eval")) {
98 - check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'eval'.");  
99 - br_eval(parv[0], parv[1], parc == 3 ? parv[2] : ""); 98 + check((parc >= 1) && (parc <= 3), "Incorrect parameter count for 'eval'.");
  99 + if (parc == 1) {
  100 + br_eval(parv[0], "", "");
  101 + } else if (parc == 2) {
  102 + if (br::File(parv[1]).suffix() == "csv") br_eval(parv[0], "", parv[1]);
  103 + else br_eval(parv[0], parv[1], "");
  104 + } else {
  105 + br_eval(parv[0], parv[1], parv[2]);
  106 + }
100 } else if (!strcmp(fun, "plot")) { 107 } else if (!strcmp(fun, "plot")) {
101 check(parc >= 2, "Incorrect parameter count for 'plot'."); 108 check(parc >= 2, "Incorrect parameter count for 'plot'.");
102 br_plot(parc-1, parv, parv[parc-1], true); 109 br_plot(parc-1, parv, parv[parc-1], true);
@@ -194,7 +201,7 @@ private: @@ -194,7 +201,7 @@ private:
194 "-train <gallery> ... <gallery> [{model}]\n" 201 "-train <gallery> ... <gallery> [{model}]\n"
195 "-enroll <input_gallery> ... <input_gallery> {output_gallery}\n" 202 "-enroll <input_gallery> ... <input_gallery> {output_gallery}\n"
196 "-compare <target_gallery> <query_gallery> [{output}]\n" 203 "-compare <target_gallery> <query_gallery> [{output}]\n"
197 - "-eval <simmat> <mask> [{csv}]\n" 204 + "-eval <simmat> [<mask>] [{csv}]\n"
198 "-plot <file> ... <file> {destination}\n" 205 "-plot <file> ... <file> {destination}\n"
199 "\n" 206 "\n"
200 "==== Other Commands ====\n" 207 "==== Other Commands ====\n"
openbr/core/bee.cpp
@@ -105,7 +105,7 @@ void BEE::writeSigset(const QString &amp;sigset, const br::FileList &amp;files, bool ign @@ -105,7 +105,7 @@ void BEE::writeSigset(const QString &amp;sigset, const br::FileList &amp;files, bool ign
105 } 105 }
106 106
107 template <typename T> 107 template <typename T>
108 -Mat readMatrix(const br::File &matrix) 108 +Mat readMatrix(const br::File &matrix, QString *targetSigset = NULL, QString *querySigset = NULL)
109 { 109 {
110 // Special case matrix construction 110 // Special case matrix construction
111 if (matrix == "Identity") { 111 if (matrix == "Identity") {
@@ -150,9 +150,11 @@ Mat readMatrix(const br::File &amp;matrix) @@ -150,9 +150,11 @@ Mat readMatrix(const br::File &amp;matrix)
150 bool isDistance = (format[0] == 'D'); 150 bool isDistance = (format[0] == 'D');
151 if (format[1] != '2') qFatal("Invalid matrix header."); 151 if (format[1] != '2') qFatal("Invalid matrix header.");
152 152
153 - // Skip sigset lines  
154 - file.readLine();  
155 - file.readLine(); 153 + // Read sigsets
  154 + if (targetSigset != NULL) *targetSigset = file.readLine().simplified();
  155 + else file.readLine();
  156 + if (querySigset != NULL) *querySigset = file.readLine().simplified();
  157 + else file.readLine();
156 158
157 // Get matrix size 159 // Get matrix size
158 QStringList words = QString(file.readLine()).split(" "); 160 QStringList words = QString(file.readLine()).split(" ");
@@ -172,9 +174,9 @@ Mat readMatrix(const br::File &amp;matrix) @@ -172,9 +174,9 @@ Mat readMatrix(const br::File &amp;matrix)
172 return result; 174 return result;
173 } 175 }
174 176
175 -Mat BEE::readSimmat(const br::File &simmat) 177 +Mat BEE::readSimmat(const br::File &simmat, QString *targetSigset, QString *querySigset)
176 { 178 {
177 - return readMatrix<Simmat_t>(simmat); 179 + return readMatrix<Simmat_t>(simmat, targetSigset, querySigset);
178 } 180 }
179 181
180 Mat BEE::readMask(const br::File &mask) 182 Mat BEE::readMask(const br::File &mask)
@@ -198,9 +200,9 @@ void writeMatrix(const Mat &amp;m, const QString &amp;matrix, const QString &amp;targetSigse @@ -198,9 +200,9 @@ void writeMatrix(const Mat &amp;m, const QString &amp;matrix, const QString &amp;targetSigse
198 QtUtils::touchDir(file); 200 QtUtils::touchDir(file);
199 bool success = file.open(QFile::WriteOnly); if (!success) qFatal("Unable to open %s for writing.", qPrintable(matrix)); 201 bool success = file.open(QFile::WriteOnly); if (!success) qFatal("Unable to open %s for writing.", qPrintable(matrix));
200 file.write("S2\n"); 202 file.write("S2\n");
201 - file.write(qPrintable(QFileInfo(targetSigset).fileName())); 203 + file.write(qPrintable(targetSigset));
202 file.write("\n"); 204 file.write("\n");
203 - file.write(qPrintable(QFileInfo(querySigset).fileName())); 205 + file.write(qPrintable(querySigset));
204 file.write("\n"); 206 file.write("\n");
205 file.write("M"); 207 file.write("M");
206 file.write(qPrintable(matrixType)); 208 file.write(qPrintable(matrixType));
openbr/core/bee.h
@@ -39,7 +39,7 @@ namespace BEE @@ -39,7 +39,7 @@ namespace BEE
39 void writeSigset(const QString &sigset, const br::FileList &files, bool ignoreMetadata = false); 39 void writeSigset(const QString &sigset, const br::FileList &files, bool ignoreMetadata = false);
40 40
41 // Matrix IO 41 // Matrix IO
42 - cv::Mat readSimmat(const br::File &simmat); 42 + cv::Mat readSimmat(const br::File &simmat, QString *targetSigset = NULL, QString *querySigset = NULL);
43 cv::Mat readMask(const br::File &mask); 43 cv::Mat readMask(const br::File &mask);
44 void writeSimmat(const cv::Mat &m, const QString &simmat, const QString &targetSigset = "Unknown_Target", const QString &querySigset = "Unknown_Query"); 44 void writeSimmat(const cv::Mat &m, const QString &simmat, const QString &targetSigset = "Unknown_Target", const QString &querySigset = "Unknown_Query");
45 void writeMask(const cv::Mat &m, const QString &mask, const QString &targetSigset = "Unknown_Target", const QString &querySigset = "Unknown_Query"); 45 void writeMask(const cv::Mat &m, const QString &mask, const QString &targetSigset = "Unknown_Target", const QString &querySigset = "Unknown_Query");
openbr/core/plot.cpp
@@ -112,21 +112,37 @@ static float getTAR(const QList&lt;OperatingPoint&gt; &amp;operatingPoints, float FAR) @@ -112,21 +112,37 @@ static float getTAR(const QList&lt;OperatingPoint&gt; &amp;operatingPoints, float FAR)
112 112
113 float Evaluate(const QString &simmat, const QString &mask, const QString &csv) 113 float Evaluate(const QString &simmat, const QString &mask, const QString &csv)
114 { 114 {
115 - qDebug("Evaluating %s with %s", qPrintable(simmat), qPrintable(mask));  
116 -  
117 - // Read files  
118 - const Mat scores = BEE::readSimmat(simmat);  
119 - File maskFile(mask);  
120 - maskFile.set("rows", scores.rows);  
121 - maskFile.set("columns", scores.cols);  
122 - const Mat masks = BEE::readMask(maskFile);  
123 - if (scores.size() != masks.size()) qFatal("Simmat (%i,%i) / Mask (%i,%i) size mismatch.", scores.rows, scores.cols, masks.rows, masks.cols); 115 + qDebug("Evaluating %s%s%s",
  116 + qPrintable(simmat),
  117 + mask.isEmpty() ? "" : qPrintable(" with " + mask),
  118 + csv.isEmpty() ? "" : qPrintable(" to " + csv));
  119 +
  120 + // Read similarity matrix
  121 + QString target, query;
  122 + const Mat scores = BEE::readSimmat(simmat, &target, &query);
  123 +
  124 + // Read mask matrix
  125 + Mat truth;
  126 + if (mask.isEmpty()) {
  127 + // Use the galleries specified in the similarity matrix
  128 + truth = BEE::makeMask(TemplateList::fromGallery(target).files(),
  129 + TemplateList::fromGallery(query).files());
  130 + } else {
  131 + File maskFile(mask);
  132 + maskFile.set("rows", scores.rows);
  133 + maskFile.set("columns", scores.cols);
  134 + truth = BEE::readMask(maskFile);
  135 + }
124 136
125 - return Evaluate(scores, masks, csv); 137 + return Evaluate(scores, truth, csv);
126 } 138 }
127 139
128 float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) 140 float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv)
129 { 141 {
  142 + if (simmat.size() != mask.size())
  143 + qFatal("Similarity matrix (%ix%i) differs in size from mask matrix (%ix%i).",
  144 + simmat.rows, simmat.cols, mask.rows, mask.cols);
  145 +
130 const int Max_Points = 500; 146 const int Max_Points = 500;
131 float result = -1; 147 float result = -1;
132 148
openbr/core/plot.h
@@ -26,7 +26,7 @@ namespace br @@ -26,7 +26,7 @@ namespace br
26 { 26 {
27 27
28 void Confusion(const QString &file, float score, int &true_positives, int &false_positives, int &true_negatives, int &false_negatives); 28 void Confusion(const QString &file, float score, int &true_positives, int &false_positives, int &true_negatives, int &false_negatives);
29 -float Evaluate(const QString &simmat, const QString &mask, const QString &csv = ""); // Returns TAR @ FAR = 0.01 29 +float Evaluate(const QString &simmat, const QString &mask = "", const QString &csv = ""); // Returns TAR @ FAR = 0.01
30 float Evaluate(const cv::Mat &scores, const cv::Mat &masks, const QString &csv = ""); 30 float Evaluate(const cv::Mat &scores, const cv::Mat &masks, const QString &csv = "");
31 bool Plot(const QStringList &files, const br::File &destination, bool show = false); 31 bool Plot(const QStringList &files, const br::File &destination, bool show = false);
32 bool PlotMetadata(const QStringList &files, const QString &destination, bool show = false); 32 bool PlotMetadata(const QStringList &files, const QString &destination, bool show = false);
openbr/openbr_plugin.cpp
@@ -411,6 +411,7 @@ TemplateList TemplateList::fromGallery(const br::File &amp;gallery) @@ -411,6 +411,7 @@ TemplateList TemplateList::fromGallery(const br::File &amp;gallery)
411 newTemplates[i].file.append(gallery.localMetadata()); 411 newTemplates[i].file.append(gallery.localMetadata());
412 newTemplates[i].file.append(file.localMetadata()); 412 newTemplates[i].file.append(file.localMetadata());
413 newTemplates[i].file.set("Index", i+templates.size()); 413 newTemplates[i].file.set("Index", i+templates.size());
  414 + newTemplates[i].file.set("Gallery", gallery.name);
414 if (newTemplates[i].file.getBool("allPartitions")) { 415 if (newTemplates[i].file.getBool("allPartitions")) {
415 if (crossValidate > 0) { 416 if (crossValidate > 0) {
416 // Set template to the first parition 417 // Set template to the first parition
openbr/plugins/output.cpp
@@ -148,7 +148,10 @@ class mtxOutput : public MatrixOutput @@ -148,7 +148,10 @@ class mtxOutput : public MatrixOutput
148 ~mtxOutput() 148 ~mtxOutput()
149 { 149 {
150 if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return; 150 if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return;
151 - BEE::writeSimmat(data, file.name); 151 + BEE::writeSimmat(data,
  152 + file.name,
  153 + targetFiles.first().get<QString>("Gallery", "Unknown_Target"),
  154 + queryFiles.first().get<QString>("Gallery", "Unknown_Query"));
152 } 155 }
153 }; 156 };
154 157
scripts/helloWorld.sh
@@ -40,3 +40,4 @@ br -algorithm Eigenfaces -path MEDS/img -compare MEDS/sigset/MEDS_frontal_target @@ -40,3 +40,4 @@ br -algorithm Eigenfaces -path MEDS/img -compare MEDS/sigset/MEDS_frontal_target
40 # br -algorithm Eigenfaces -path MEDS/img -enroll MEDS/sigset/MEDS_frontal_target.xml target.gal -enroll MEDS/sigset/MEDS_frontal_query.xml query.gal -compare target.gal query.gal scores.mtx 40 # br -algorithm Eigenfaces -path MEDS/img -enroll MEDS/sigset/MEDS_frontal_target.xml target.gal -enroll MEDS/sigset/MEDS_frontal_query.xml query.gal -compare target.gal query.gal scores.mtx
41 41
42 # Evaluate Eigenfaces accuracy 42 # Evaluate Eigenfaces accuracy
  43 +br -eval scores.mtx results.csv -plot results.csv results.pdf