Commit bd13c06ee2a748c98139e2f4a7526385206294be

Authored by Scott Klum
1 parent fa4557b7

Fixed crossValidation allPartitions bug

openbr/openbr_plugin.cpp
@@ -388,33 +388,44 @@ TemplateList TemplateList::fromGallery(const br::File &gallery) @@ -388,33 +388,44 @@ TemplateList TemplateList::fromGallery(const br::File &gallery)
388 const int crossValidate = gallery.get<int>("crossValidate"); 388 const int crossValidate = gallery.get<int>("crossValidate");
389 if (crossValidate > 0) srand(0); 389 if (crossValidate > 0) srand(0);
390 390
391 - for (int i=newTemplates.size()-1; i>=0; i--) {  
392 - newTemplates[i].file.set("Index", i+templates.size());  
393 - newTemplates[i].file.set("Gallery", gallery.name);  
394 -  
395 - if (crossValidate > 0) {  
396 - if (newTemplates[i].file.getBool("duplicatePartitions")) {  
397 - // The duplicatePartitions flag is used to add target images  
398 - // crossValidate times to the simmat/mask  
399 - // when multiple training sets are being used  
400 -  
401 - // Set template to the first parition  
402 - newTemplates[i].file.set("Partition", QVariant(0));  
403 -  
404 - // Insert templates for all the other partitions  
405 - for (int j=crossValidate-1; j>=1; j--) {  
406 - Template allPartitionTemplate = newTemplates[i];  
407 - allPartitionTemplate.file.set("Partition", j);  
408 - newTemplates.insert(i+1, allPartitionTemplate); 391 + if (gallery.getBool("leaveOneOut", 0)) {
  392 + QStringList subjects = File::get(newTemplates.files(),"Subject","-1");
  393 + subjects.
  394 + // Get QStringLists of unique subjects
  395 +
  396 + // For each list of unique subjects, decide randomly which to test on
  397 + for (int i = 0; i < subjects.size(); i++) {
  398 + if (subjects
  399 + }
  400 + } else {
  401 + for (int i=newTemplates.size()-1; i>=0; i--) {
  402 + newTemplates[i].file.set("Index", i+templates.size());
  403 + newTemplates[i].file.set("Gallery", gallery.name);
  404 +
  405 + if (crossValidate > 0) {
  406 + if (newTemplates[i].file.getBool("duplicatePartitions")) {
  407 + // The duplicatePartitions flag is used to add target images
  408 + // crossValidate times to the simmat/mask
  409 + // when multiple training sets are being used
  410 +
  411 + // Set template to the first parition
  412 + newTemplates[i].file.set("Partition", QVariant(0));
  413 +
  414 + // Insert templates for all the other partitions
  415 + for (int j=crossValidate-1; j>0; j--) {
  416 + Template duplicatePartitionsTemplate = newTemplates[i];
  417 + duplicatePartitionsTemplate.file.set("Partition", j);
  418 + newTemplates.insert(i+1, duplicatePartitionsTemplate);
  419 + }
  420 + } else if (newTemplates[i].file.getBool("allPartitions")) {
  421 + // The allPartitions flag is used to add an extended set
  422 + // of target images to every partition
  423 + newTemplates[i].file.set("Partition", -1);
  424 + } else {
  425 + const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get<QString>("Subject").toLatin1(), QCryptographicHash::Md5);
  426 + // Select the right 8 hex characters so that it can be represented as a 64 bit integer without overflow
  427 + newTemplates[i].file.set("Partition", md5.toHex().right(8).toULongLong(0, 16) % crossValidate);
409 } 428 }
410 - } else if (newTemplates[i].file.getBool("allPartitions")) {  
411 - // The allPartitions flag is used to add an extended set  
412 - // of target images to every partition  
413 - newTemplates[i].file.set("Partition", -1);  
414 - } else {  
415 - const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get<QString>("Subject").toLatin1(), QCryptographicHash::Md5);  
416 - // Select the right 8 hex characters so that it can be represented as a 64 bit integer without overflow  
417 - newTemplates[i].file.set("Partition", md5.toHex().right(8).toULongLong(0, 16) % crossValidate);  
418 } 429 }
419 } 430 }
420 } 431 }
openbr/plugins/eyes.cpp
@@ -182,8 +182,8 @@ private: @@ -182,8 +182,8 @@ private:
182 float second_eye_y = (right_rect.y + maxLoc.y)*gray.rows/height+roi.y; 182 float second_eye_y = (right_rect.y + maxLoc.y)*gray.rows/height+roi.y;
183 183
184 dst.m() = src.m(); 184 dst.m() = src.m();
185 - dst.file.appendPoint(QPointF(first_eye_x, first_eye_y));  
186 - dst.file.appendPoint(QPointF(second_eye_x, second_eye_y)); 185 + //dst.file.appendPoint(QPointF(first_eye_x, first_eye_y));
  186 + //dst.file.appendPoint(QPointF(second_eye_x, second_eye_y));
187 dst.file.set("First_Eye", QPointF(first_eye_x, first_eye_y)); 187 dst.file.set("First_Eye", QPointF(first_eye_x, first_eye_y));
188 dst.file.set("Second_Eye", QPointF(second_eye_x, second_eye_y)); 188 dst.file.set("Second_Eye", QPointF(second_eye_x, second_eye_y));
189 dst.file.set("Face", QRect(roi.x, roi.y, roi.width, roi.height)); 189 dst.file.set("Face", QRect(roi.x, roi.y, roi.width, roi.height));
openbr/plugins/landmarks.cpp
@@ -164,6 +164,7 @@ class DelaunayTransform : public UntrainableTransform @@ -164,6 +164,7 @@ class DelaunayTransform : public UntrainableTransform
164 164
165 if (points.empty() || rects.empty()) { 165 if (points.empty() || rects.empty()) {
166 dst = src; 166 dst = src;
  167 + dst.file.clearRects();
167 qWarning("Delauney triangulation failed because points or rects are empty."); 168 qWarning("Delauney triangulation failed because points or rects are empty.");
168 return; 169 return;
169 } 170 }
@@ -292,11 +293,54 @@ class DelaunayTransform : public UntrainableTransform @@ -292,11 +293,54 @@ class DelaunayTransform : public UntrainableTransform
292 dst.file.setRects(QList<QRectF>() << OpenCVUtils::fromRect(boundingBox)); 293 dst.file.setRects(QList<QRectF>() << OpenCVUtils::fromRect(boundingBox));
293 } 294 }
294 } 295 }
295 -  
296 }; 296 };
297 297
298 BR_REGISTER(Transform, DelaunayTransform) 298 BR_REGISTER(Transform, DelaunayTransform)
299 299
  300 +/*!
  301 + * \ingroup transforms
  302 + * \brief Loads a set of fiduciary points from a .dat file
  303 + * \author Scott Klum \cite sklum
  304 + */
  305 +class LoadLandmarksTransform : public UntrainableTransform
  306 +{
  307 + Q_OBJECT
  308 +
  309 + Q_PROPERTY(QString filePath READ get_filePath WRITE set_filePath RESET reset_filePath STORED false)
  310 + BR_PROPERTY(QString, filePath, QString())
  311 +
  312 + void project(const Template &src, Template &dst) const
  313 + {
  314 + dst = src;
  315 +
  316 + QString path = Globals->path + "/" + src.file.baseName() + ".dat";
  317 +
  318 + QFile f(path);
  319 + if (!f.open(QIODevice::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(path));
  320 +
  321 + QList<QPointF> landmarks;
  322 + while(!f.atEnd()) {
  323 + QByteArray line = f.readLine();
  324 + QString pointSet(line);
  325 + pointSet = pointSet.simplified();
  326 + if (!pointSet.isEmpty()) {
  327 + QStringList points = pointSet.split(" ");
  328 + landmarks.append(QPointF(points[0].toFloat(),points[1].toFloat()));
  329 + }
  330 + }
  331 +
  332 + dst.file.set("rightEye", landmarks[16]);
  333 + dst.file.set("leftEye", landmarks[18]);
  334 +
  335 + landmarks.removeAt(18);
  336 + landmarks.removeAt(16);
  337 +
  338 + dst.file.appendPoints(landmarks);
  339 + }
  340 +};
  341 +
  342 +BR_REGISTER(Transform, LoadLandmarksTransform)
  343 +
300 } // namespace br 344 } // namespace br
301 345
302 #include "landmarks.moc" 346 #include "landmarks.moc"
openbr/plugins/output.cpp
@@ -259,7 +259,8 @@ class rrOutput : public MatrixOutput @@ -259,7 +259,8 @@ class rrOutput : public MatrixOutput
259 { 259 {
260 if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return; 260 if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return;
261 const int limit = file.get<int>("limit", 20); 261 const int limit = file.get<int>("limit", 20);
262 - const bool byLine = file.get<bool>("byLine", false); 262 + const bool byLine = file.getBool("byLine");
  263 + const bool simple = file.getBool("simple");
263 const float threshold = file.get<float>("threshold", -std::numeric_limits<float>::max()); 264 const float threshold = file.get<float>("threshold", -std::numeric_limits<float>::max());
264 265
265 QStringList lines; 266 QStringList lines;
@@ -273,7 +274,8 @@ class rrOutput : public MatrixOutput @@ -273,7 +274,8 @@ class rrOutput : public MatrixOutput
273 if (pair.first < threshold) break; 274 if (pair.first < threshold) break;
274 File target = targetFiles[pair.second]; 275 File target = targetFiles[pair.second];
275 target.set("Score", QString::number(pair.first)); 276 target.set("Score", QString::number(pair.first));
276 - files.append(target.flat()); 277 + if (simple) files.append(target.baseName() + " " + QString::number(pair.first));
  278 + else files.append(target.flat());
277 } 279 }
278 lines.append(files.join(byLine ? "\n" : ",")); 280 lines.append(files.join(byLine ? "\n" : ","));
279 } 281 }
openbr/plugins/validate.cpp
@@ -53,10 +53,10 @@ class CrossValidateTransform : public MetaTransform @@ -53,10 +53,10 @@ class CrossValidateTransform : public MetaTransform
53 53
54 void project(const Template &src, Template &dst) const 54 void project(const Template &src, Template &dst) const
55 { 55 {
56 - // If the src partition is greater than the number of training partitions, 56 + // If the src partition is 1,
57 // assume that projection should be done using the same training data for all partitions. 57 // assume that projection should be done using the same training data for all partitions.
58 int partition = src.file.get<int>("Partition", 0); 58 int partition = src.file.get<int>("Partition", 0);
59 - if (partition >= transforms.size()) partition = 0; 59 + if (partition == -1 ) partition = 0;
60 60
61 transforms[partition]->project(src, dst); 61 transforms[partition]->project(src, dst);
62 } 62 }