Commit 84b41a656d4380e7bd37e99399ba7c8f11518394
1 parent
2fe3c0ea
added -eval shortcut
Showing
8 changed files
with
55 additions
and
25 deletions
app/br/br.cpp
| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | #include <stdio.h> |
| 21 | 21 | #include <stdlib.h> |
| 22 | 22 | #include <string.h> |
| 23 | -#include <openbr/openbr.h> | |
| 23 | +#include <openbr/openbr_plugin.h> | |
| 24 | 24 | |
| 25 | 25 | /*! |
| 26 | 26 | * \defgroup cli Command Line Interface |
| ... | ... | @@ -95,8 +95,15 @@ public: |
| 95 | 95 | check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'compare'."); |
| 96 | 96 | br_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); |
| 97 | 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 | 107 | } else if (!strcmp(fun, "plot")) { |
| 101 | 108 | check(parc >= 2, "Incorrect parameter count for 'plot'."); |
| 102 | 109 | br_plot(parc-1, parv, parv[parc-1], true); |
| ... | ... | @@ -194,7 +201,7 @@ private: |
| 194 | 201 | "-train <gallery> ... <gallery> [{model}]\n" |
| 195 | 202 | "-enroll <input_gallery> ... <input_gallery> {output_gallery}\n" |
| 196 | 203 | "-compare <target_gallery> <query_gallery> [{output}]\n" |
| 197 | - "-eval <simmat> <mask> [{csv}]\n" | |
| 204 | + "-eval <simmat> [<mask>] [{csv}]\n" | |
| 198 | 205 | "-plot <file> ... <file> {destination}\n" |
| 199 | 206 | "\n" |
| 200 | 207 | "==== Other Commands ====\n" | ... | ... |
openbr/core/bee.cpp
| ... | ... | @@ -105,7 +105,7 @@ void BEE::writeSigset(const QString &sigset, const br::FileList &files, bool ign |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 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 | 110 | // Special case matrix construction |
| 111 | 111 | if (matrix == "Identity") { |
| ... | ... | @@ -150,9 +150,11 @@ Mat readMatrix(const br::File &matrix) |
| 150 | 150 | bool isDistance = (format[0] == 'D'); |
| 151 | 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 | 159 | // Get matrix size |
| 158 | 160 | QStringList words = QString(file.readLine()).split(" "); |
| ... | ... | @@ -172,9 +174,9 @@ Mat readMatrix(const br::File &matrix) |
| 172 | 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 | 182 | Mat BEE::readMask(const br::File &mask) |
| ... | ... | @@ -198,9 +200,9 @@ void writeMatrix(const Mat &m, const QString &matrix, const QString &targetSigse |
| 198 | 200 | QtUtils::touchDir(file); |
| 199 | 201 | bool success = file.open(QFile::WriteOnly); if (!success) qFatal("Unable to open %s for writing.", qPrintable(matrix)); |
| 200 | 202 | file.write("S2\n"); |
| 201 | - file.write(qPrintable(QFileInfo(targetSigset).fileName())); | |
| 203 | + file.write(qPrintable(targetSigset)); | |
| 202 | 204 | file.write("\n"); |
| 203 | - file.write(qPrintable(QFileInfo(querySigset).fileName())); | |
| 205 | + file.write(qPrintable(querySigset)); | |
| 204 | 206 | file.write("\n"); |
| 205 | 207 | file.write("M"); |
| 206 | 208 | file.write(qPrintable(matrixType)); | ... | ... |
openbr/core/bee.h
| ... | ... | @@ -39,7 +39,7 @@ namespace BEE |
| 39 | 39 | void writeSigset(const QString &sigset, const br::FileList &files, bool ignoreMetadata = false); |
| 40 | 40 | |
| 41 | 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 | 43 | cv::Mat readMask(const br::File &mask); |
| 44 | 44 | void writeSimmat(const cv::Mat &m, const QString &simmat, const QString &targetSigset = "Unknown_Target", const QString &querySigset = "Unknown_Query"); |
| 45 | 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<OperatingPoint> &operatingPoints, float FAR) |
| 112 | 112 | |
| 113 | 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 | 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 | 146 | const int Max_Points = 500; |
| 131 | 147 | float result = -1; |
| 132 | 148 | ... | ... |
openbr/core/plot.h
| ... | ... | @@ -26,7 +26,7 @@ namespace br |
| 26 | 26 | { |
| 27 | 27 | |
| 28 | 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 | 30 | float Evaluate(const cv::Mat &scores, const cv::Mat &masks, const QString &csv = ""); |
| 31 | 31 | bool Plot(const QStringList &files, const br::File &destination, bool show = false); |
| 32 | 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 &gallery) |
| 411 | 411 | newTemplates[i].file.append(gallery.localMetadata()); |
| 412 | 412 | newTemplates[i].file.append(file.localMetadata()); |
| 413 | 413 | newTemplates[i].file.set("Index", i+templates.size()); |
| 414 | + newTemplates[i].file.set("Gallery", gallery.name); | |
| 414 | 415 | if (newTemplates[i].file.getBool("allPartitions")) { |
| 415 | 416 | if (crossValidate > 0) { |
| 416 | 417 | // Set template to the first parition | ... | ... |
openbr/plugins/output.cpp
| ... | ... | @@ -148,7 +148,10 @@ class mtxOutput : public MatrixOutput |
| 148 | 148 | ~mtxOutput() |
| 149 | 149 | { |
| 150 | 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 | 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 | 42 | # Evaluate Eigenfaces accuracy |
| 43 | +br -eval scores.mtx results.csv -plot results.csv results.pdf | ... | ... |