Commit 52e35c0919c9729e1319077cca42a26e4e2f9e20

Authored by Josh Klontz
2 parents 8472460e 03208ae7

Merge branch 'master' of https://github.com/biometrics/openbr

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"