Commit 52e35c0919c9729e1319077cca42a26e4e2f9e20
Merge branch 'master' of https://github.com/biometrics/openbr
Showing
5 changed files
with
61 additions
and
21 deletions
openbr/core/core.cpp
| @@ -223,7 +223,7 @@ struct AlgorithmCore | @@ -223,7 +223,7 @@ struct AlgorithmCore | ||
| 223 | if (!output.fileName().contains("%1")) qFatal("Output file name missing split number place marker (%%1)"); | 223 | if (!output.fileName().contains("%1")) qFatal("Output file name missing split number place marker (%%1)"); |
| 224 | partitionSizes = output.getList<int>("split"); | 224 | partitionSizes = output.getList<int>("split"); |
| 225 | for (int i=0; i<partitionSizes.size(); i++) { | 225 | for (int i=0; i<partitionSizes.size(); i++) { |
| 226 | - File splitOutputFile = output.fileName().arg(i); | 226 | + File splitOutputFile = output.name.arg(i); |
| 227 | outputFiles.append(splitOutputFile); | 227 | outputFiles.append(splitOutputFile); |
| 228 | } | 228 | } |
| 229 | } | 229 | } |
openbr/plugins/distance.cpp
| @@ -145,7 +145,7 @@ BR_REGISTER(Distance, DefaultDistance) | @@ -145,7 +145,7 @@ BR_REGISTER(Distance, DefaultDistance) | ||
| 145 | * \author Josh Klontz \cite jklontz | 145 | * \author Josh Klontz \cite jklontz |
| 146 | * | 146 | * |
| 147 | * The templates are compared using each br::Distance in order. | 147 | * The templates are compared using each br::Distance in order. |
| 148 | - * If the result of the comparison with any given distance is -INT_MAX then this result is returned early. | 148 | + * If the result of the comparison with any given distance is -FLOAT_MAX then this result is returned early. |
| 149 | * Otherwise the returned result is the value of comparing the templates using the last br::Distance. | 149 | * Otherwise the returned result is the value of comparing the templates using the last br::Distance. |
| 150 | */ | 150 | */ |
| 151 | class PipeDistance : public Distance | 151 | class PipeDistance : public Distance |
openbr/plugins/output.cpp
| @@ -268,7 +268,7 @@ class rrOutput : public MatrixOutput | @@ -268,7 +268,7 @@ class rrOutput : public MatrixOutput | ||
| 268 | 268 | ||
| 269 | for (int i=0; i<queryFiles.size(); i++) { | 269 | for (int i=0; i<queryFiles.size(); i++) { |
| 270 | QStringList files; | 270 | QStringList files; |
| 271 | - files.append(queryFiles[i]); | 271 | + if (simple) files.append(queryFiles[i]); |
| 272 | 272 | ||
| 273 | typedef QPair<float,int> Pair; | 273 | typedef QPair<float,int> Pair; |
| 274 | foreach (const Pair &pair, Common::Sort(OpenCVUtils::matrixToVector<float>(data.row(i)), true, limit)) { | 274 | foreach (const Pair &pair, Common::Sort(OpenCVUtils::matrixToVector<float>(data.row(i)), true, limit)) { |
| @@ -384,7 +384,7 @@ class evalOutput : public MatrixOutput | @@ -384,7 +384,7 @@ class evalOutput : public MatrixOutput | ||
| 384 | 384 | ||
| 385 | double mean, stddev; | 385 | double mean, stddev; |
| 386 | Common::MeanStdDev(TARs, &mean, &stddev); | 386 | Common::MeanStdDev(TARs, &mean, &stddev); |
| 387 | - qDebug("TAR @ FAR = 0.001: %.3f +/- %.3f", mean, stddev); | 387 | + qDebug("TAR @ FAR = 0.01: %.3f +/- %.3f", mean, stddev); |
| 388 | } | 388 | } |
| 389 | } | 389 | } |
| 390 | } | 390 | } |
openbr/plugins/stasm4.cpp
| @@ -5,7 +5,6 @@ | @@ -5,7 +5,6 @@ | ||
| 5 | #include "openbr/core/qtutils.h" | 5 | #include "openbr/core/qtutils.h" |
| 6 | #include "openbr/core/opencvutils.h" | 6 | #include "openbr/core/opencvutils.h" |
| 7 | #include <QString> | 7 | #include <QString> |
| 8 | -#include <Eigen/SVD> | ||
| 9 | 8 | ||
| 10 | using namespace std; | 9 | using namespace std; |
| 11 | using namespace cv; | 10 | using namespace cv; |
| @@ -77,7 +76,7 @@ class StasmTransform : public UntrainableTransform | @@ -77,7 +76,7 @@ class StasmTransform : public UntrainableTransform | ||
| 77 | 76 | ||
| 78 | StasmCascadeClassifier *stasmCascade = stasmCascadeResource.acquire(); | 77 | StasmCascadeClassifier *stasmCascade = stasmCascadeResource.acquire(); |
| 79 | 78 | ||
| 80 | - int foundface; | 79 | + int foundFace = 0; |
| 81 | int nLandmarks = stasm_NLANDMARKS; | 80 | int nLandmarks = stasm_NLANDMARKS; |
| 82 | float landmarks[2 * stasm_NLANDMARKS]; | 81 | float landmarks[2 * stasm_NLANDMARKS]; |
| 83 | 82 | ||
| @@ -109,13 +108,14 @@ class StasmTransform : public UntrainableTransform | @@ -109,13 +108,14 @@ class StasmTransform : public UntrainableTransform | ||
| 109 | else if (i == 39) /*Stasm Left Eye*/ { eyes[2*i] = leftEye.x(); eyes[2*i+1] = leftEye.y(); } | 108 | else if (i == 39) /*Stasm Left Eye*/ { eyes[2*i] = leftEye.x(); eyes[2*i+1] = leftEye.y(); } |
| 110 | else { eyes[2*i] = 0; eyes[2*i+1] = 0; } | 109 | else { eyes[2*i] = 0; eyes[2*i+1] = 0; } |
| 111 | } | 110 | } |
| 112 | - } else qFatal("Unable to interpret pinned eyes."); | 111 | + stasm_search_pinned(landmarks, eyes, reinterpret_cast<const char*>(src.m().data), src.m().cols, src.m().rows, NULL); |
| 113 | 112 | ||
| 114 | - stasm_search_pinned(landmarks, eyes, reinterpret_cast<const char*>(src.m().data), src.m().cols, src.m().rows, NULL); | 113 | + // The ASM in Stasm is guaranteed to converge in this case |
| 114 | + foundFace = 1; | ||
| 115 | + } | ||
| 116 | + } | ||
| 115 | 117 | ||
| 116 | - // The ASM in Stasm is guaranteed to converge in this case | ||
| 117 | - foundface = 1; | ||
| 118 | - } stasm_search_single(&foundface, landmarks, reinterpret_cast<const char*>(src.m().data), src.m().cols, src.m().rows, *stasmCascade, NULL, NULL); | 118 | + if (!foundFace) stasm_search_single(&foundFace, landmarks, reinterpret_cast<const char*>(src.m().data), src.m().cols, src.m().rows, *stasmCascade, NULL, NULL); |
| 119 | 119 | ||
| 120 | if (stasm3Format) { | 120 | if (stasm3Format) { |
| 121 | nLandmarks = 76; | 121 | nLandmarks = 76; |
| @@ -130,8 +130,8 @@ class StasmTransform : public UntrainableTransform | @@ -130,8 +130,8 @@ class StasmTransform : public UntrainableTransform | ||
| 130 | dst.file.clearRects(); | 130 | dst.file.clearRects(); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | - if (!foundface) { | ||
| 134 | - qWarning("No face found in %s", qPrintable(src.file.fileName())); | 133 | + if (!foundFace) { |
| 134 | + qWarning("No face found in %s.", qPrintable(src.file.fileName())); | ||
| 135 | } else { | 135 | } else { |
| 136 | for (int i = 0; i < nLandmarks; i++) { | 136 | for (int i = 0; i < nLandmarks; i++) { |
| 137 | QPointF point(landmarks[2 * i], landmarks[2 * i + 1]); | 137 | QPointF point(landmarks[2 * i], landmarks[2 * i + 1]); |
openbr/plugins/validate.cpp
| @@ -74,9 +74,7 @@ class CrossValidateTransform : public MetaTransform | @@ -74,9 +74,7 @@ class CrossValidateTransform : public MetaTransform | ||
| 74 | // Remove template that was repeated to make the testOnly template | 74 | // Remove template that was repeated to make the testOnly template |
| 75 | if (subjectIndices.size() > 1 && subjectIndices.size() <= i) { | 75 | if (subjectIndices.size() > 1 && subjectIndices.size() <= i) { |
| 76 | removed.append(subjectIndices[i%subjectIndices.size()]); | 76 | removed.append(subjectIndices[i%subjectIndices.size()]); |
| 77 | - } | ||
| 78 | - // For the time being, we don't support addition training data added to every fold in the case of leaveOneImageOut | ||
| 79 | - else if (partitionsBuffer[j] == i) { | 77 | + } else if (partitionsBuffer[j] == i) { |
| 80 | removed.append(j); | 78 | removed.append(j); |
| 81 | } | 79 | } |
| 82 | 80 | ||
| @@ -88,10 +86,6 @@ class CrossValidateTransform : public MetaTransform | @@ -88,10 +86,6 @@ class CrossValidateTransform : public MetaTransform | ||
| 88 | } else { | 86 | } else { |
| 89 | j--; | 87 | j--; |
| 90 | } | 88 | } |
| 91 | - } else if (partitions[j] == -1) { | ||
| 92 | - // Keep data for training, but modify the partition so we project into the correct space | ||
| 93 | - partitionedData[j].file.set("Partition",i); | ||
| 94 | - j--; | ||
| 95 | } else if (partitions[j] == i) { | 89 | } else if (partitions[j] == i) { |
| 96 | // Remove data, it's designated for testing | 90 | // Remove data, it's designated for testing |
| 97 | partitionedData.removeAt(j); | 91 | partitionedData.removeAt(j); |
| @@ -106,7 +100,19 @@ class CrossValidateTransform : public MetaTransform | @@ -106,7 +100,19 @@ class CrossValidateTransform : public MetaTransform | ||
| 106 | 100 | ||
| 107 | void project(const Template &src, Template &dst) const | 101 | void project(const Template &src, Template &dst) const |
| 108 | { | 102 | { |
| 109 | - transforms[src.file.get<int>("Partition", 0)]->project(src, dst); | 103 | + // Remember, the partition should never be -1 |
| 104 | + // since it is assumed that the allPartitions | ||
| 105 | + // flag is only used during comparison | ||
| 106 | + // (i.e. only used when making a mask) | ||
| 107 | + if (src.file.getBool("Train", false)) dst = src; | ||
| 108 | + else { | ||
| 109 | + // If we want to duplicate templates but use the same training data | ||
| 110 | + // for all partitions (i.e. transforms.size() == 1), we need to | ||
| 111 | + // restrict the partition | ||
| 112 | + int partition = src.file.get<int>("Partition", 0); | ||
| 113 | + partition = (partition >= transforms.size()) ? 0 : partition; | ||
| 114 | + transforms[partition]->project(src, dst); | ||
| 115 | + } | ||
| 110 | } | 116 | } |
| 111 | 117 | ||
| 112 | void store(QDataStream &stream) const | 118 | void store(QDataStream &stream) const |
| @@ -231,6 +237,40 @@ class MetadataDistance : public Distance | @@ -231,6 +237,40 @@ class MetadataDistance : public Distance | ||
| 231 | 237 | ||
| 232 | BR_REGISTER(Distance, MetadataDistance) | 238 | BR_REGISTER(Distance, MetadataDistance) |
| 233 | 239 | ||
| 240 | +/*! | ||
| 241 | + * \ingroup distances | ||
| 242 | + * \brief Sets distance to -FLOAT_MAX if a target template has/doesn't have a key. | ||
| 243 | + * \author Scott Klum \cite sklum | ||
| 244 | + */ | ||
| 245 | +class RejectDistance : public Distance | ||
| 246 | +{ | ||
| 247 | + Q_OBJECT | ||
| 248 | + | ||
| 249 | + Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false) | ||
| 250 | + BR_PROPERTY(QStringList, keys, QStringList()) | ||
| 251 | + Q_PROPERTY(bool rejectIfContains READ get_rejectIfContains WRITE set_rejectIfContains RESET reset_rejectIfContains STORED false) | ||
| 252 | + BR_PROPERTY(bool, rejectIfContains, false) | ||
| 253 | + | ||
| 254 | + float compare(const Template &a, const Template &b) const | ||
| 255 | + { | ||
| 256 | + (void) b; | ||
| 257 | + bool keep = true; | ||
| 258 | + | ||
| 259 | + foreach (const QString &key, keys) { | ||
| 260 | + if ((rejectIfContains && a.file.contains(key)) || | ||
| 261 | + (!rejectIfContains && !a.file.contains(key))) | ||
| 262 | + keep = false; | ||
| 263 | + | ||
| 264 | + if (!keep) return -std::numeric_limits<float>::max(); | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + return 0; | ||
| 268 | + } | ||
| 269 | +}; | ||
| 270 | + | ||
| 271 | + | ||
| 272 | +BR_REGISTER(Distance, RejectDistance) | ||
| 273 | + | ||
| 234 | } // namespace br | 274 | } // namespace br |
| 235 | 275 | ||
| 236 | #include "validate.moc" | 276 | #include "validate.moc" |