diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index 832d7b4..6330d63 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -388,33 +388,44 @@ TemplateList TemplateList::fromGallery(const br::File &gallery) const int crossValidate = gallery.get("crossValidate"); if (crossValidate > 0) srand(0); - for (int i=newTemplates.size()-1; i>=0; i--) { - newTemplates[i].file.set("Index", i+templates.size()); - newTemplates[i].file.set("Gallery", gallery.name); - - if (crossValidate > 0) { - if (newTemplates[i].file.getBool("duplicatePartitions")) { - // The duplicatePartitions flag is used to add target images - // crossValidate times to the simmat/mask - // when multiple training sets are being used - - // Set template to the first parition - newTemplates[i].file.set("Partition", QVariant(0)); - - // Insert templates for all the other partitions - for (int j=crossValidate-1; j>=1; j--) { - Template allPartitionTemplate = newTemplates[i]; - allPartitionTemplate.file.set("Partition", j); - newTemplates.insert(i+1, allPartitionTemplate); + if (gallery.getBool("leaveOneOut", 0)) { + QStringList subjects = File::get(newTemplates.files(),"Subject","-1"); + subjects. + // Get QStringLists of unique subjects + + // For each list of unique subjects, decide randomly which to test on + for (int i = 0; i < subjects.size(); i++) { + if (subjects + } + } else { + for (int i=newTemplates.size()-1; i>=0; i--) { + newTemplates[i].file.set("Index", i+templates.size()); + newTemplates[i].file.set("Gallery", gallery.name); + + if (crossValidate > 0) { + if (newTemplates[i].file.getBool("duplicatePartitions")) { + // The duplicatePartitions flag is used to add target images + // crossValidate times to the simmat/mask + // when multiple training sets are being used + + // Set template to the first parition + newTemplates[i].file.set("Partition", QVariant(0)); + + // Insert templates for all the other partitions + for (int j=crossValidate-1; j>0; j--) { + Template duplicatePartitionsTemplate = newTemplates[i]; + duplicatePartitionsTemplate.file.set("Partition", j); + newTemplates.insert(i+1, duplicatePartitionsTemplate); + } + } else if (newTemplates[i].file.getBool("allPartitions")) { + // The allPartitions flag is used to add an extended set + // of target images to every partition + newTemplates[i].file.set("Partition", -1); + } else { + const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get("Subject").toLatin1(), QCryptographicHash::Md5); + // Select the right 8 hex characters so that it can be represented as a 64 bit integer without overflow + newTemplates[i].file.set("Partition", md5.toHex().right(8).toULongLong(0, 16) % crossValidate); } - } else if (newTemplates[i].file.getBool("allPartitions")) { - // The allPartitions flag is used to add an extended set - // of target images to every partition - newTemplates[i].file.set("Partition", -1); - } else { - const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get("Subject").toLatin1(), QCryptographicHash::Md5); - // Select the right 8 hex characters so that it can be represented as a 64 bit integer without overflow - newTemplates[i].file.set("Partition", md5.toHex().right(8).toULongLong(0, 16) % crossValidate); } } } diff --git a/openbr/plugins/eyes.cpp b/openbr/plugins/eyes.cpp index e8e2ae9..dd56767 100644 --- a/openbr/plugins/eyes.cpp +++ b/openbr/plugins/eyes.cpp @@ -182,8 +182,8 @@ private: float second_eye_y = (right_rect.y + maxLoc.y)*gray.rows/height+roi.y; dst.m() = src.m(); - dst.file.appendPoint(QPointF(first_eye_x, first_eye_y)); - dst.file.appendPoint(QPointF(second_eye_x, second_eye_y)); + //dst.file.appendPoint(QPointF(first_eye_x, first_eye_y)); + //dst.file.appendPoint(QPointF(second_eye_x, second_eye_y)); dst.file.set("First_Eye", QPointF(first_eye_x, first_eye_y)); dst.file.set("Second_Eye", QPointF(second_eye_x, second_eye_y)); dst.file.set("Face", QRect(roi.x, roi.y, roi.width, roi.height)); diff --git a/openbr/plugins/landmarks.cpp b/openbr/plugins/landmarks.cpp index 9f06f7f..41da7d7 100644 --- a/openbr/plugins/landmarks.cpp +++ b/openbr/plugins/landmarks.cpp @@ -164,6 +164,7 @@ class DelaunayTransform : public UntrainableTransform if (points.empty() || rects.empty()) { dst = src; + dst.file.clearRects(); qWarning("Delauney triangulation failed because points or rects are empty."); return; } @@ -292,11 +293,54 @@ class DelaunayTransform : public UntrainableTransform dst.file.setRects(QList() << OpenCVUtils::fromRect(boundingBox)); } } - }; BR_REGISTER(Transform, DelaunayTransform) +/*! + * \ingroup transforms + * \brief Loads a set of fiduciary points from a .dat file + * \author Scott Klum \cite sklum + */ +class LoadLandmarksTransform : public UntrainableTransform +{ + Q_OBJECT + + Q_PROPERTY(QString filePath READ get_filePath WRITE set_filePath RESET reset_filePath STORED false) + BR_PROPERTY(QString, filePath, QString()) + + void project(const Template &src, Template &dst) const + { + dst = src; + + QString path = Globals->path + "/" + src.file.baseName() + ".dat"; + + QFile f(path); + if (!f.open(QIODevice::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(path)); + + QList landmarks; + while(!f.atEnd()) { + QByteArray line = f.readLine(); + QString pointSet(line); + pointSet = pointSet.simplified(); + if (!pointSet.isEmpty()) { + QStringList points = pointSet.split(" "); + landmarks.append(QPointF(points[0].toFloat(),points[1].toFloat())); + } + } + + dst.file.set("rightEye", landmarks[16]); + dst.file.set("leftEye", landmarks[18]); + + landmarks.removeAt(18); + landmarks.removeAt(16); + + dst.file.appendPoints(landmarks); + } +}; + +BR_REGISTER(Transform, LoadLandmarksTransform) + } // namespace br #include "landmarks.moc" diff --git a/openbr/plugins/output.cpp b/openbr/plugins/output.cpp index 2b75582..971681e 100644 --- a/openbr/plugins/output.cpp +++ b/openbr/plugins/output.cpp @@ -259,7 +259,8 @@ class rrOutput : public MatrixOutput { if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return; const int limit = file.get("limit", 20); - const bool byLine = file.get("byLine", false); + const bool byLine = file.getBool("byLine"); + const bool simple = file.getBool("simple"); const float threshold = file.get("threshold", -std::numeric_limits::max()); QStringList lines; @@ -273,7 +274,8 @@ class rrOutput : public MatrixOutput if (pair.first < threshold) break; File target = targetFiles[pair.second]; target.set("Score", QString::number(pair.first)); - files.append(target.flat()); + if (simple) files.append(target.baseName() + " " + QString::number(pair.first)); + else files.append(target.flat()); } lines.append(files.join(byLine ? "\n" : ",")); } diff --git a/openbr/plugins/validate.cpp b/openbr/plugins/validate.cpp index 8b3a174..ba946d7 100644 --- a/openbr/plugins/validate.cpp +++ b/openbr/plugins/validate.cpp @@ -53,10 +53,10 @@ class CrossValidateTransform : public MetaTransform void project(const Template &src, Template &dst) const { - // If the src partition is greater than the number of training partitions, + // If the src partition is 1, // assume that projection should be done using the same training data for all partitions. int partition = src.file.get("Partition", 0); - if (partition >= transforms.size()) partition = 0; + if (partition == -1 ) partition = 0; transforms[partition]->project(src, dst); }