diff --git a/openbr/core/bee.cpp b/openbr/core/bee.cpp index f137dd3..8ee25e5 100644 --- a/openbr/core/bee.cpp +++ b/openbr/core/bee.cpp @@ -112,7 +112,7 @@ void BEE::writeSigset(const QString &sigset, const br::FileList &files, bool ign metadata.append("Rects=\"["+landmarks.join(",")+"]\""); } } - lines.append("\t("Label",file.fileName()) +"\">"); + lines.append("\t"); lines.append("\t\t"); lines.append("\t"); } diff --git a/openbr/core/eval.cpp b/openbr/core/eval.cpp index 2dcf4cc..6a2d7c7 100644 --- a/openbr/core/eval.cpp +++ b/openbr/core/eval.cpp @@ -167,7 +167,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) if ((falsePositives > previousFalsePositives) && (truePositives > previousTruePositives)) { // Restrict the extreme ends of the curve - if ((truePositives >= 10) && (falsePositives < impostorCount/2)) + //if ((truePositives >= 10) && (falsePositives < impostorCount/2)) operatingPoints.append(OperatingPoint(thresh, float(falsePositives)/impostorCount, float(truePositives)/genuineCount)); previousFalsePositives = falsePositives; previousTruePositives = truePositives; diff --git a/openbr/core/plot.cpp b/openbr/core/plot.cpp index 021fc5d..7f7eecb 100644 --- a/openbr/core/plot.cpp +++ b/openbr/core/plot.cpp @@ -236,7 +236,7 @@ bool Plot(const QStringList &files, const File &destination, bool show) QString(", xlab=\"False Accept Rate\", ylab=\"False Reject Rate\") + geom_abline(alpha=0.5, colour=\"grey\", linetype=\"dashed\") + theme_minimal()") + (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + - QString(" + scale_x_log10(labels=percent, limits=c(min(DET$X),1)) + scale_y_log10(labels=percent) + annotation_logticks()\n\n"))); + QString(" + scale_x_log10(labels=percent, limits=c(min(DET$X),1)) + scale_y_continuous(labels=percent)\n\n"))); p.file.write(qPrintable(QString("qplot(X, data=SD, geom=\"histogram\", fill=Y, position=\"identity\", alpha=I(1/2)") + QString(", xlab=\"Score%1\"").arg((p.flip ? p.major.size : p.minor.size) > 1 ? " / " + (p.flip ? p.major.header : p.minor.header) : QString()) + diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index 103d44f..31cdb73 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -441,10 +441,10 @@ TemplateList TemplateList::fromGallery(const br::File &gallery) // of target images to every partition newTemplates[i].file.set("Partition", -1); } else { - // Direct use of "Label" is not general -cao - const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get("Label").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); + // Direct use of "Label" is not general -cao + const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get("Label").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/crop.cpp b/openbr/plugins/crop.cpp index 30a75ea..d742fd4 100644 --- a/openbr/plugins/crop.cpp +++ b/openbr/plugins/crop.cpp @@ -60,8 +60,13 @@ class ROITransform : public UntrainableTransform void project(const Template &src, Template &dst) const { - foreach (const QRectF &rect, src.file.rects()) - dst += src.m()(OpenCVUtils::toRect(rect)); + if (src.file.rects().empty()) { + dst = src; + qWarning("No rects present in file."); + } + else + foreach (const QRectF &rect, src.file.rects()) + dst += src.m()(OpenCVUtils::toRect(rect)); } }; diff --git a/openbr/plugins/distance.cpp b/openbr/plugins/distance.cpp index 7f0cf71..d4a3808 100644 --- a/openbr/plugins/distance.cpp +++ b/openbr/plugins/distance.cpp @@ -310,7 +310,7 @@ class OnlineDistance : public Distance Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false) Q_PROPERTY(float alpha READ get_alpha WRITE set_alpha RESET reset_alpha STORED false) BR_PROPERTY(br::Distance*, distance, NULL) - BR_PROPERTY(float, alpha, 0.1f); + BR_PROPERTY(float, alpha, 0.1f) mutable QHash scoreHash; mutable QMutex mutex; diff --git a/openbr/plugins/draw.cpp b/openbr/plugins/draw.cpp index 304431f..9c57127 100644 --- a/openbr/plugins/draw.cpp +++ b/openbr/plugins/draw.cpp @@ -46,11 +46,11 @@ class DrawTransform : public UntrainableTransform void project(const Template &src, Template &dst) const { const Scalar color(0,255,0); - const Scalar verboseColor(255, 255, 0); + const Scalar verboseColor(0, 0, 0); dst.m() = inPlace ? src.m() : src.m().clone(); if (points) { - const QList pointsList = OpenCVUtils::toPoints(src.file.namedPoints() + src.file.points()); + const QList pointsList = OpenCVUtils::toPoints(src.file.points()); for (int i=0; i("newFormat",QString()); - QString destination = file.name + "/" + (file.getBool("preservePath") ? t.file.path()+"/" : QString()); + QString destination = file.name + "/fold_" + QString::number(t.file.get("Partition")) + "/target/" + (file.getBool("preservePath") ? t.file.path()+"/" : QString()); destination += (newFormat.isEmpty() ? t.file.fileName() : t.file.baseName()+newFormat); QMutexLocker diskLocker(&diskLock); // Windows prefers to crash when writing to disk in parallel diff --git a/openbr/plugins/misc.cpp b/openbr/plugins/misc.cpp index 09c214b..5a5ce50 100644 --- a/openbr/plugins/misc.cpp +++ b/openbr/plugins/misc.cpp @@ -382,50 +382,38 @@ BR_REGISTER(Transform, RegexPropertyTransform) /*! * \ingroup transforms - * \brief Remove templates with the specified file extension or metadata value. - * \author Josh Klontz \cite jklontz + * \brief Calculate metadata statistics + * \author Scott Klum \cite sklum */ -class RemoveTemplatesTransform : public UntrainableMetaTransform +class MetadataStatisticsTransform : public Transform { Q_OBJECT - Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false) - Q_PROPERTY(QString key READ get_key WRITE set_key RESET reset_key STORED false) - BR_PROPERTY(QString, regexp, "") - BR_PROPERTY(QString, key, "") + Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false) + BR_PROPERTY(QStringList, keys, QStringList()) - void project(const Template &src, Template &dst) const + void train(const TemplateList &data) { - const QRegularExpression re(regexp); - const QRegularExpressionMatch match = re.match(key.isEmpty() ? src.file.suffix() : src.file.get(key)); - if (match.hasMatch()) dst = Template(); - else dst = src; - } -}; + QHash statHash; -BR_REGISTER(Transform, RemoveTemplatesTransform) + foreach (const Template &t, data) { + foreach (const QString &key, keys) { + QString value = t.file.get(key, QString()); -/*! - * \ingroup transforms - * \brief Remove template metadata with the specified key(s). - * \author Josh Klontz \cite jklontz - */ -class RemoveMetadataTransform : public UntrainableMetaTransform -{ - Q_OBJECT - Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false) - BR_PROPERTY(QString, regexp, "") + if (value.isEmpty()) continue; + int count = statHash.value(value,0); + statHash.value(value,count+1); + } + } + foreach (const QString &key, statHash.keys()) fprintf(stdout, "%s: %s\n", qPrintable(key), qPrintable(statHash.value(key))); + } void project(const Template &src, Template &dst) const { dst = src; - const QRegularExpression re(regexp); - foreach (const QString &key, dst.file.localKeys()) - if (re.match(key).hasMatch()) - dst.file.remove(key); } }; -BR_REGISTER(Transform, RemoveMetadataTransform) +BR_REGISTER(Transform, MetadataStatisticsTransform) /*! * \ingroup transforms diff --git a/openbr/plugins/output.cpp b/openbr/plugins/output.cpp index f2a3be4..934901c 100644 --- a/openbr/plugins/output.cpp +++ b/openbr/plugins/output.cpp @@ -76,14 +76,29 @@ class csvOutput : public MatrixOutput { if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return; QStringList lines; - lines.append("File," + targetFiles.names().join(",")); - for (int i=0; icrossValidate == 0) { + for (int i=0; icrossValidate; k++) { + lines.clear(); + for (int i=0; i("Partition"); + if (queryPartition != k) continue; + QStringList words; + QList targetPartitions = targetFiles.crossValidationPartitions(); + for (int j=0; j sample = Common::RandSample(dimsOut, weights); Mat xMap(1, dimsOut, CV_16SC1); diff --git a/openbr/plugins/stasm4.cpp b/openbr/plugins/stasm4.cpp index c8195b1..c26df92 100644 --- a/openbr/plugins/stasm4.cpp +++ b/openbr/plugins/stasm4.cpp @@ -56,6 +56,8 @@ class StasmTransform : public UntrainableTransform Q_PROPERTY(bool stasm3Format READ get_stasm3Format WRITE set_stasm3Format RESET reset_stasm3Format STORED false) BR_PROPERTY(bool, stasm3Format, false) + Q_PROPERTY(bool clearLandmarks READ get_clearLandmarks WRITE set_clearLandmarks RESET reset_clearLandmarks STORED false) + BR_PROPERTY(bool, clearLandmarks, false) Resource stasmCascadeResource; @@ -69,6 +71,8 @@ class StasmTransform : public UntrainableTransform { if (src.m().channels() != 1) qFatal("Stasm expects single channel matrices."); + dst = src; + StasmCascadeClassifier *stasmCascade = stasmCascadeResource.acquire(); int foundface; @@ -83,10 +87,20 @@ class StasmTransform : public UntrainableTransform stasmCascadeResource.release(stasmCascade); - if (!foundface) qWarning("No face found in %s", qPrintable(src.file.fileName())); - else { - for (int i = 0; i < nLandmarks; i++) - dst.file.appendPoint(QPointF(landmarks[2 * i], landmarks[2 * i + 1])); + if (clearLandmarks) { + dst.file.clearPoints(); + dst.file.clearRects(); + } + + if (!foundface) { + qWarning("No face found in %s", qPrintable(src.file.fileName())); + } else { + for (int i = 0; i < nLandmarks; i++) { + QPointF point(landmarks[2 * i], landmarks[2 * i + 1]); + dst.file.appendPoint(point); + if (i == 38) dst.file.set("StasmRightEye",point); + if (i == 39) dst.file.set("StasmLeftEye", point); + } } dst.m() = src.m(); diff --git a/openbr/plugins/template.cpp b/openbr/plugins/template.cpp index dd5f88d..cd68a32 100644 --- a/openbr/plugins/template.cpp +++ b/openbr/plugins/template.cpp @@ -1,4 +1,5 @@ #include "openbr_internal.h" +#include namespace br { @@ -25,6 +26,30 @@ class RetainTransform : public UntrainableTransform BR_REGISTER(Transform, RetainTransform) +/*! + * \ingroup transforms + * \brief Remove templates with the specified file extension or metadata value. + * \author Josh Klontz \cite jklontz + */ +class RemoveTemplatesTransform : public UntrainableMetaTransform +{ + Q_OBJECT + Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false) + Q_PROPERTY(QString key READ get_key WRITE set_key RESET reset_key STORED false) + BR_PROPERTY(QString, regexp, "") + BR_PROPERTY(QString, key, "") + + void project(const Template &src, Template &dst) const + { + const QRegularExpression re(regexp); + const QRegularExpressionMatch match = re.match(key.isEmpty() ? src.file.suffix() : src.file.get(key)); + if (match.hasMatch()) dst = Template(); + else dst = src; + } +}; + +BR_REGISTER(Transform, RemoveTemplatesTransform) + } // namespace br #include "template.moc"