From 72a5968a012360dda117defa4d8e0521806a31b5 Mon Sep 17 00:00:00 2001 From: Charles Otto Date: Tue, 14 May 2013 23:32:20 -0400 Subject: [PATCH] Further changes to label/subject --- app/examples/age_estimation.cpp | 2 +- openbr/core/bee.cpp | 14 ++++++++------ openbr/core/classify.cpp | 6 +++--- openbr/core/cluster.cpp | 4 +++- openbr/core/core.cpp | 2 -- openbr/core/opencvutils.cpp | 11 +++++++++++ openbr/core/opencvutils.h | 2 ++ openbr/frvt2012.cpp | 5 +++-- openbr/gui/classifier.cpp | 5 ++--- openbr/openbr_plugin.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- openbr/openbr_plugin.h | 15 ++++++++++++++- openbr/plugins/eigen3.cpp | 6 ++++-- openbr/plugins/gallery.cpp | 7 +++---- openbr/plugins/independent.cpp | 14 ++++++++------ openbr/plugins/meta.cpp | 3 ++- openbr/plugins/normalize.cpp | 3 ++- openbr/plugins/output.cpp | 6 ++++-- openbr/plugins/pixel.cpp | 2 ++ openbr/plugins/quality.cpp | 8 ++++---- openbr/plugins/quantize.cpp | 5 +++-- openbr/plugins/quantize2.cpp | 2 +- openbr/plugins/svm.cpp | 22 ++++++++++++++++++++-- 22 files changed, 153 insertions(+), 48 deletions(-) diff --git a/app/examples/age_estimation.cpp b/app/examples/age_estimation.cpp index d8ae1e6..c2a90e5 100644 --- a/app/examples/age_estimation.cpp +++ b/app/examples/age_estimation.cpp @@ -29,7 +29,7 @@ static void printTemplate(const br::Template &t) { - printf("%s age: %d\n", qPrintable(t.file.fileName()), int(t.file.get("Label"))); + printf("%s age: %d\n", qPrintable(t.file.fileName()), int(t.file.get("Subject"))); } int main(int argc, char *argv[]) diff --git a/openbr/core/bee.cpp b/openbr/core/bee.cpp index 9522cc9..bfd3103 100644 --- a/openbr/core/bee.cpp +++ b/openbr/core/bee.cpp @@ -260,26 +260,28 @@ void BEE::makeMask(const QString &targetInput, const QString &queryInput, const cv::Mat BEE::makeMask(const br::FileList &targets, const br::FileList &queries, int partition) { - QList targetLabels = targets.collectValues("Label"); - QList queryLabels = queries.collectValues("Label"); + // Would like to use indexProperty for this, but didn't make a version of that for Filelist yet + // -cao + QList targetLabels = targets.collectValues("Subject", "-1"); + QList queryLabels = queries.collectValues("Subject", "-1"); QList targetPartitions = targets.crossValidationPartitions(); QList queryPartitions = queries.crossValidationPartitions(); Mat mask(queries.size(), targets.size(), CV_8UC1); for (int i=0; i("Label")-truth[i].file.get("Label"), 2.f); - truthValues.append(QString::number(truth[i].file.get("Label"))); - predictedValues.append(QString::number(predicted[i].file.get("Label"))); + rmsError += pow(predicted[i].file.get("Subject")-truth[i].file.get("Subject"), 2.f); + truthValues.append(QString::number(truth[i].file.get("Subject"))); + predictedValues.append(QString::number(predicted[i].file.get("Subject"))); } QStringList rSource; diff --git a/openbr/core/cluster.cpp b/openbr/core/cluster.cpp index b4bcff0..40482e8 100644 --- a/openbr/core/cluster.cpp +++ b/openbr/core/cluster.cpp @@ -278,7 +278,9 @@ void br::EvalClustering(const QString &csv, const QString &input) { qDebug("Evaluating %s against %s", qPrintable(csv), qPrintable(input)); - QList labels = TemplateList::fromGallery(input).files().collectValues("Label"); + // We assume clustering algorithms store assigned cluster labels as integers (since the clusters are + // not named). + QList labels = TemplateList::fromGallery(input).files().collectValues("Subject"); QHash labelToIndex; int nClusters = 0; diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index 1d5c353..ca5c07c 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -78,7 +78,6 @@ struct AlgorithmCore const bool hasComparer = !distance.isNull(); out << hasComparer; if (hasComparer) distance->store(out); - out << Globals->subjects; // Compress and save to file QtUtils::writeFile(model, data, -1); @@ -98,7 +97,6 @@ struct AlgorithmCore transform->load(in); bool hasDistance; in >> hasDistance; if (hasDistance) distance->load(in); - in >> Globals->subjects; } File getMemoryGallery(const File &file) const diff --git a/openbr/core/opencvutils.cpp b/openbr/core/opencvutils.cpp index fb5622c..48601e9 100644 --- a/openbr/core/opencvutils.cpp +++ b/openbr/core/opencvutils.cpp @@ -119,6 +119,17 @@ Mat OpenCVUtils::toMat(const QList &src, int rows) return dst; } +Mat OpenCVUtils::toMat(const QList &src, int rows) +{ + if (rows == -1) rows = src.size(); + int columns = src.isEmpty() ? 0 : src.size() / rows; + if (rows*columns != src.size()) qFatal("Invalid matrix size."); + Mat dst(rows, columns, CV_32FC1); + for (int i=0; i(i/columns,i%columns) = src[i]; + return dst; +} + Mat OpenCVUtils::toMat(const QList &src) { if (src.isEmpty()) return Mat(); diff --git a/openbr/core/opencvutils.h b/openbr/core/opencvutils.h index ecf6067..0e49fa0 100644 --- a/openbr/core/opencvutils.h +++ b/openbr/core/opencvutils.h @@ -35,6 +35,8 @@ namespace OpenCVUtils // To image cv::Mat toMat(const QList &src, int rows = -1); + cv::Mat toMat(const QList &src, int rows = -1); + cv::Mat toMat(const QList &src); // Data organized one matrix per row cv::Mat toMatByRow(const QList &src); // Data organized one row per row diff --git a/openbr/frvt2012.cpp b/openbr/frvt2012.cpp index 3e3b07f..baf0b85 100644 --- a/openbr/frvt2012.cpp +++ b/openbr/frvt2012.cpp @@ -132,7 +132,7 @@ int32_t SdkEstimator::estimate_age(const ONEFACE &input_face, int32_t &age) TemplateList templates; templates.append(templateFromONEFACE(input_face)); templates >> *frvt2012_age_transform.data(); - age = templates.first().file.get("Label"); + age = templates.first().file.get("Subject"); return templates.first().file.failed() ? 4 : 0; } @@ -141,6 +141,7 @@ int32_t SdkEstimator::estimate_gender(const ONEFACE &input_face, int8_t &gender, TemplateList templates; templates.append(templateFromONEFACE(input_face)); templates >> *frvt2012_gender_transform.data(); - mf = gender = templates.first().file.get("Label"); + // TODO: lookup gender strings/expected int outputs -cao + mf = gender = templates.first().file.get("Subject") == "Male" ? 0 : 1; return templates.first().file.failed() ? 4 : 0; } diff --git a/openbr/gui/classifier.cpp b/openbr/gui/classifier.cpp index 10bf549..2df9f5e 100644 --- a/openbr/gui/classifier.cpp +++ b/openbr/gui/classifier.cpp @@ -42,16 +42,15 @@ void Classifier::_classify(File file) if (!f.contains("Label")) continue; - // What's with the special casing -cao if (algorithm == "GenderClassification") { key = "Gender"; value = (f.get("Subject")); } else if (algorithm == "AgeRegression") { key = "Age"; - value = QString::number(int(f.get("Label")+0.5)) + " Years"; + value = QString::number(int(f.get("Subject")+0.5)) + " Years"; } else { key = algorithm; - value = QString::number(f.get("Label")); + value = f.get("Subject"); } break; } diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index ca41c9c..0d6a8b1 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -435,11 +435,13 @@ TemplateList TemplateList::fromGallery(const br::File &gallery) return templates; } +// indexes some property, assigns an integer id to each unique value of propName +// stores the index values in "Label" of the output template list -cao TemplateList TemplateList::relabel(const TemplateList &tl, const QString & propName) { - const QList originalLabels = tl.collectValues(propName); - QHash labelTable; - foreach (int label, originalLabels) + const QList originalLabels = tl.collectValues(propName); + QHash labelTable; + foreach (const QString & label, originalLabels) if (!labelTable.contains(label)) labelTable.insert(label, labelTable.size()); @@ -449,6 +451,52 @@ TemplateList TemplateList::relabel(const TemplateList &tl, const QString & propN return result; } +QList TemplateList::indexProperty(const QString & propName, QHash * valueMap,QHash * reverseLookup) const +{ + QHash dummyForwards; + QHash dummyBackwards; + + if (!valueMap) valueMap = &dummyForwards; + if (!reverseLookup) reverseLookup = &dummyBackwards; + + return indexProperty(propName, *valueMap, *reverseLookup); +} + +QList TemplateList::indexProperty(const QString & propName, QHash & valueMap, QHash & reverseLookup) const +{ + valueMap.clear(); + reverseLookup.clear(); + + const QList originalLabels = collectValues(propName); + foreach (const QVariant & label, originalLabels) { + QString labelString = label.toString(); + if (!valueMap.contains(labelString)) { + reverseLookup.insert(valueMap.size(), label); + valueMap.insert(labelString, valueMap.size()); + } + } + + QList result; + for (int i=0; i TemplateList::applyIndex(const QString & propName, const QHash & valueMap) const +{ + const QList originalLabels = collectValues(propName); + + QList result; + for (int i=0; i(row,column); - return Globals->subjects.key(label, QString::number(label)); + // problem -cao + return QString::number(label); } return QString::number(data.at(row,column)); } diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index b970e45..8b2bfe9 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -306,6 +306,15 @@ struct BR_EXPORT FileList : public QList values.append(f.get(propName)); return values; } + template + QList collectValues(const QString & propName, T defaultValue) const + { + QList values; values.reserve(size()); + foreach (const File &f, *this) + values.append(f.contains(propName) ? f.get(propName) : defaultValue); + return values; + } + QList crossValidationPartitions() const; /*!< \brief Returns the cross-validation partition (default=0) for each file in the list. */ int failures() const; /*!< \brief Returns the number of files with br::File::failed(). */ }; @@ -393,6 +402,11 @@ struct TemplateList : public QList