Commit 11123de77a9ea7935825f8f6b3d803bd9217b783
1 parent
edbb16c9
introduced evalOutput
Showing
5 changed files
with
56 additions
and
26 deletions
openbr/core/bee.cpp
| @@ -234,22 +234,26 @@ void BEE::writeMask(const Mat &m, const QString &mask, const QString &targetSigs | @@ -234,22 +234,26 @@ void BEE::writeMask(const Mat &m, const QString &mask, const QString &targetSigs | ||
| 234 | void BEE::makeMask(const QString &targetInput, const QString &queryInput, const QString &mask) | 234 | void BEE::makeMask(const QString &targetInput, const QString &queryInput, const QString &mask) |
| 235 | { | 235 | { |
| 236 | qDebug("Making mask from %s and %s to %s", qPrintable(targetInput), qPrintable(queryInput), qPrintable(mask)); | 236 | qDebug("Making mask from %s and %s to %s", qPrintable(targetInput), qPrintable(queryInput), qPrintable(mask)); |
| 237 | + FileList targes = TemplateList::fromGallery(targetInput).files(); | ||
| 238 | + FileList queries = (queryInput == ".") ? targes : TemplateList::fromGallery(queryInput).files(); | ||
| 239 | + writeMask(makeMask(targes, queries), mask, targetInput, queryInput); | ||
| 240 | +} | ||
| 237 | 241 | ||
| 238 | - FileList targetFiles = TemplateList::fromGallery(targetInput).files(); | ||
| 239 | - FileList queryFiles = (queryInput == ".") ? targetFiles : TemplateList::fromGallery(queryInput).files(); | ||
| 240 | - QList<float> targetLabels = targetFiles.labels(); | ||
| 241 | - QList<float> queryLabels = queryFiles.labels(); | ||
| 242 | - QList<int> targetPartitions = targetFiles.crossValidationPartitions(); | ||
| 243 | - QList<int> queryPartitions = queryFiles.crossValidationPartitions(); | ||
| 244 | - | ||
| 245 | - Mat vals(queryFiles.size(), targetFiles.size(), CV_8UC1); | ||
| 246 | - for (int i=0; i<queryFiles.size(); i++) { | ||
| 247 | - const QString &fileA = queryFiles[i]; | 242 | +cv::Mat BEE::makeMask(const br::FileList &targets, const br::FileList &queries) |
| 243 | +{ | ||
| 244 | + QList<float> targetLabels = targets.labels(); | ||
| 245 | + QList<float> queryLabels = queries.labels(); | ||
| 246 | + QList<int> targetPartitions = targets.crossValidationPartitions(); | ||
| 247 | + QList<int> queryPartitions = queries.crossValidationPartitions(); | ||
| 248 | + | ||
| 249 | + Mat mask(queries.size(), targets.size(), CV_8UC1); | ||
| 250 | + for (int i=0; i<queries.size(); i++) { | ||
| 251 | + const QString &fileA = queries[i]; | ||
| 248 | const int labelA = queryLabels[i]; | 252 | const int labelA = queryLabels[i]; |
| 249 | const int partitionA = queryPartitions[i]; | 253 | const int partitionA = queryPartitions[i]; |
| 250 | 254 | ||
| 251 | - for (int j=0; j<targetFiles.size(); j++) { | ||
| 252 | - const QString &fileB = targetFiles[j]; | 255 | + for (int j=0; j<targets.size(); j++) { |
| 256 | + const QString &fileB = targets[j]; | ||
| 253 | const int labelB = targetLabels[j]; | 257 | const int labelB = targetLabels[j]; |
| 254 | const int partitionB = targetPartitions[j]; | 258 | const int partitionB = targetPartitions[j]; |
| 255 | 259 | ||
| @@ -260,10 +264,11 @@ void BEE::makeMask(const QString &targetInput, const QString &queryInput, const | @@ -260,10 +264,11 @@ void BEE::makeMask(const QString &targetInput, const QString &queryInput, const | ||
| 260 | else if (partitionA != partitionB) val = DontCare; | 264 | else if (partitionA != partitionB) val = DontCare; |
| 261 | else if (labelA == labelB) val = Match; | 265 | else if (labelA == labelB) val = Match; |
| 262 | else val = NonMatch; | 266 | else val = NonMatch; |
| 263 | - vals.at<Mask_t>(i,j) = val; | 267 | + mask.at<Mask_t>(i,j) = val; |
| 264 | } | 268 | } |
| 265 | } | 269 | } |
| 266 | - writeMask(vals, mask, targetInput, queryInput); | 270 | + |
| 271 | + return mask; | ||
| 267 | } | 272 | } |
| 268 | 273 | ||
| 269 | void BEE::combineMasks(const QStringList &inputMasks, const QString &outputMask, const QString &method) | 274 | void BEE::combineMasks(const QStringList &inputMasks, const QString &outputMask, const QString &method) |
openbr/core/bee.h
| @@ -46,6 +46,7 @@ namespace BEE | @@ -46,6 +46,7 @@ namespace BEE | ||
| 46 | 46 | ||
| 47 | // Write BEE files | 47 | // Write BEE files |
| 48 | void makeMask(const QString &targetInput, const QString &queryInput, const QString &mask); | 48 | void makeMask(const QString &targetInput, const QString &queryInput, const QString &mask); |
| 49 | + cv::Mat makeMask(const br::FileList &targets, const br::FileList &queries); | ||
| 49 | void combineMasks(const QStringList &inputMasks, const QString &outputMask, const QString &method); | 50 | void combineMasks(const QStringList &inputMasks, const QString &outputMask, const QString &method); |
| 50 | } | 51 | } |
| 51 | 52 |
openbr/core/plot.cpp
| @@ -113,9 +113,6 @@ float Evaluate(const QString &simmat, const QString &mask, const QString &csv) | @@ -113,9 +113,6 @@ float Evaluate(const QString &simmat, const QString &mask, const QString &csv) | ||
| 113 | { | 113 | { |
| 114 | qDebug("Evaluating %s with %s", qPrintable(simmat), qPrintable(mask)); | 114 | qDebug("Evaluating %s with %s", qPrintable(simmat), qPrintable(mask)); |
| 115 | 115 | ||
| 116 | - const int Max_Points = 500; | ||
| 117 | - float result = -1; | ||
| 118 | - | ||
| 119 | // Read files | 116 | // Read files |
| 120 | const Mat scores = BEE::readSimmat(simmat); | 117 | const Mat scores = BEE::readSimmat(simmat); |
| 121 | File maskFile(mask); | 118 | File maskFile(mask); |
| @@ -124,13 +121,21 @@ float Evaluate(const QString &simmat, const QString &mask, const QString &csv) | @@ -124,13 +121,21 @@ float Evaluate(const QString &simmat, const QString &mask, const QString &csv) | ||
| 124 | const Mat masks = BEE::readMask(maskFile); | 121 | const Mat masks = BEE::readMask(maskFile); |
| 125 | if (scores.size() != masks.size()) qFatal("Simmat/Mask size mismatch."); | 122 | if (scores.size() != masks.size()) qFatal("Simmat/Mask size mismatch."); |
| 126 | 123 | ||
| 124 | + return Evaluate(scores, masks, csv); | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) | ||
| 128 | +{ | ||
| 129 | + const int Max_Points = 500; | ||
| 130 | + float result = -1; | ||
| 131 | + | ||
| 127 | // Make comparisons | 132 | // Make comparisons |
| 128 | - QList<Comparison> comparisons; comparisons.reserve(scores.rows*scores.cols); | 133 | + QList<Comparison> comparisons; comparisons.reserve(simmat.rows*simmat.cols); |
| 129 | int genuineCount = 0, impostorCount = 0, numNaNs = 0; | 134 | int genuineCount = 0, impostorCount = 0, numNaNs = 0; |
| 130 | - for (int i=0; i<scores.rows; i++) { | ||
| 131 | - for (int j=0; j<scores.cols; j++) { | ||
| 132 | - const BEE::Mask_t mask_val = masks.at<BEE::Mask_t>(i,j); | ||
| 133 | - const BEE::Simmat_t simmat_val = scores.at<BEE::Simmat_t>(i,j); | 135 | + for (int i=0; i<simmat.rows; i++) { |
| 136 | + for (int j=0; j<simmat.cols; j++) { | ||
| 137 | + const BEE::Mask_t mask_val = mask.at<BEE::Mask_t>(i,j); | ||
| 138 | + const BEE::Simmat_t simmat_val = simmat.at<BEE::Simmat_t>(i,j); | ||
| 134 | if (mask_val == BEE::DontCare) continue; | 139 | if (mask_val == BEE::DontCare) continue; |
| 135 | if (simmat_val != simmat_val) { numNaNs++; continue; } | 140 | if (simmat_val != simmat_val) { numNaNs++; continue; } |
| 136 | comparisons.append(Comparison(simmat_val, j, i, mask_val == BEE::Match)); | 141 | comparisons.append(Comparison(simmat_val, j, i, mask_val == BEE::Match)); |
| @@ -149,7 +154,7 @@ float Evaluate(const QString &simmat, const QString &mask, const QString &csv) | @@ -149,7 +154,7 @@ float Evaluate(const QString &simmat, const QString &mask, const QString &csv) | ||
| 149 | double genuineSum = 0, impostorSum = 0; | 154 | double genuineSum = 0, impostorSum = 0; |
| 150 | QList<OperatingPoint> operatingPoints; | 155 | QList<OperatingPoint> operatingPoints; |
| 151 | QList<float> genuines, impostors; | 156 | QList<float> genuines, impostors; |
| 152 | - QVector<int> firstGenuineReturns(scores.rows, 0); | 157 | + QVector<int> firstGenuineReturns(simmat.rows, 0); |
| 153 | 158 | ||
| 154 | int falsePositives = 0, previousFalsePositives = 0; | 159 | int falsePositives = 0, previousFalsePositives = 0; |
| 155 | int truePositives = 0, previousTruePositives = 0; | 160 | int truePositives = 0, previousTruePositives = 0; |
| @@ -202,11 +207,11 @@ float Evaluate(const QString &simmat, const QString &mask, const QString &csv) | @@ -202,11 +207,11 @@ float Evaluate(const QString &simmat, const QString &mask, const QString &csv) | ||
| 202 | // Write Metadata table | 207 | // Write Metadata table |
| 203 | QStringList lines; | 208 | QStringList lines; |
| 204 | lines.append("Plot,X,Y"); | 209 | lines.append("Plot,X,Y"); |
| 205 | - lines.append("Metadata,"+QString::number(scores.cols)+",Gallery"); | ||
| 206 | - lines.append("Metadata,"+QString::number(scores.rows)+",Probe"); | 210 | + lines.append("Metadata,"+QString::number(simmat.cols)+",Gallery"); |
| 211 | + lines.append("Metadata,"+QString::number(simmat.rows)+",Probe"); | ||
| 207 | lines.append("Metadata,"+QString::number(genuineCount)+",Genuine"); | 212 | lines.append("Metadata,"+QString::number(genuineCount)+",Genuine"); |
| 208 | lines.append("Metadata,"+QString::number(impostorCount)+",Impostor"); | 213 | lines.append("Metadata,"+QString::number(impostorCount)+",Impostor"); |
| 209 | - lines.append("Metadata,"+QString::number(scores.cols*scores.rows-(genuineCount+impostorCount))+",Ignored"); | 214 | + lines.append("Metadata,"+QString::number(simmat.cols*simmat.rows-(genuineCount+impostorCount))+",Ignored"); |
| 210 | 215 | ||
| 211 | // Write Detection Error Tradeoff (DET), PRE, REC | 216 | // Write Detection Error Tradeoff (DET), PRE, REC |
| 212 | int points = qMin(operatingPoints.size(), Max_Points); | 217 | int points = qMin(operatingPoints.size(), Max_Points); |
openbr/core/plot.h
| @@ -27,6 +27,7 @@ namespace br | @@ -27,6 +27,7 @@ namespace br | ||
| 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 | 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); |
| 31 | bool PlotMetadata(const QStringList &files, const QString &destination, bool show = false); | 32 | bool PlotMetadata(const QStringList &files, const QString &destination, bool show = false); |
| 32 | 33 |
openbr/plugins/output.cpp
| @@ -40,6 +40,7 @@ | @@ -40,6 +40,7 @@ | ||
| 40 | #include "openbr/core/bee.h" | 40 | #include "openbr/core/bee.h" |
| 41 | #include "openbr/core/common.h" | 41 | #include "openbr/core/common.h" |
| 42 | #include "openbr/core/opencvutils.h" | 42 | #include "openbr/core/opencvutils.h" |
| 43 | +#include "openbr/core/plot.h" | ||
| 43 | #include "openbr/core/qtutils.h" | 44 | #include "openbr/core/qtutils.h" |
| 44 | 45 | ||
| 45 | namespace br | 46 | namespace br |
| @@ -259,6 +260,23 @@ BR_REGISTER(Output, EmptyOutput) | @@ -259,6 +260,23 @@ BR_REGISTER(Output, EmptyOutput) | ||
| 259 | 260 | ||
| 260 | /*! | 261 | /*! |
| 261 | * \ingroup outputs | 262 | * \ingroup outputs |
| 263 | + * \brief Evaluate the output matrix. | ||
| 264 | + * \author Josh Klontz \cite jklontz | ||
| 265 | + */ | ||
| 266 | +class evalOutput : public MatrixOutput | ||
| 267 | +{ | ||
| 268 | + Q_OBJECT | ||
| 269 | + | ||
| 270 | + ~evalOutput() | ||
| 271 | + { | ||
| 272 | + Evaluate(data, BEE::makeMask(targetFiles, queryFiles), ""); | ||
| 273 | + } | ||
| 274 | +}; | ||
| 275 | + | ||
| 276 | +BR_REGISTER(Output, evalOutput) | ||
| 277 | + | ||
| 278 | +/*! | ||
| 279 | + * \ingroup outputs | ||
| 262 | * \brief Outputs highest ranked matches with scores. | 280 | * \brief Outputs highest ranked matches with scores. |
| 263 | * \author Scott Klum \cite sklum | 281 | * \author Scott Klum \cite sklum |
| 264 | */ | 282 | */ |