diff --git a/openbr/core/qtutils.cpp b/openbr/core/qtutils.cpp index 0c29616..a5529cc 100644 --- a/openbr/core/qtutils.cpp +++ b/openbr/core/qtutils.cpp @@ -285,25 +285,45 @@ void QtUtils::checkArgsSize(const QString &name, const QStringList &args, int mi if (args.size() > max) qFatal("%s expects no more than %d arguments, got %d", qPrintable(name), max, args.size()); } -QPointF QtUtils::toPoint(const QString &string) +QPointF QtUtils::toPoint(const QString &string, bool *ok) { - QStringList values = string.split(','); - if (values.size() == 2) { - values[1].chop(1); - return QPointF(values[0].mid(1).toFloat(), values[1].toFloat()); + if (string.startsWith('(') && string.endsWith(')')) { + const QStringList words = parse(string.mid(1, string.size()-2)); + if (words.size() == 2) { + float x, y; + bool okX, okY; + x = words[0].toFloat(&okX); + y = words[1].toFloat(&okY); + if (okX && okY) { + if (ok) *ok = true; + return QPointF(x, y); + } + } } - else qFatal("Failed to convert %s to QPointF format.", qPrintable(string)); + + if (ok) *ok = false; return QPointF(); } -QRectF QtUtils::toRect(const QString &string) +QRectF QtUtils::toRect(const QString &string, bool *ok) { - QStringList values = string.split(','); - if (values.size() == 4) { - values[3].chop(1); - return QRectF(values[0].mid(1).toFloat(), values[1].toFloat(), values[2].toFloat(), values[3].toFloat()); + if (string.startsWith('(') && string.endsWith(')')) { + const QStringList words = parse(string.mid(1, string.size()-2)); + if (words.size() == 4) { + float x, y, width, height; + bool okX, okY, okWidth, okHeight; + x = words[0].toFloat(&okX); + y = words[1].toFloat(&okY); + width = words[0].toFloat(&okWidth); + height = words[1].toFloat(&okHeight); + if (okX && okY && okWidth && okHeight) { + if (ok) *ok = true; + return QRectF(x, y, width, height); + } + } } - else qFatal("Failed to convert %s to QRectF format.", qPrintable(string)); + + if (ok) *ok = false; return QRectF(); } diff --git a/openbr/core/qtutils.h b/openbr/core/qtutils.h index 4ad4743..2d842af 100644 --- a/openbr/core/qtutils.h +++ b/openbr/core/qtutils.h @@ -62,8 +62,8 @@ namespace QtUtils QString shortTextHash(QString string); QStringList parse(QString args, char split = ','); void checkArgsSize(const QString &name, const QStringList &args, int min, int max); - QPointF toPoint(const QString &string); - QRectF toRect(const QString &string); + QPointF toPoint(const QString &string, bool *ok = NULL); + QRectF toRect(const QString &string, bool *ok = NULL); /**** Process Utilities ****/ bool runRScript(const QString &file); diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index 804c1ee..55d7627 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -125,6 +125,18 @@ QVariant File::value(const QString &key) const return m_metadata.contains(key) ? m_metadata.value(key) : Globals->property(qPrintable(key)); } +QVariant File::parse(const QString &value) +{ + bool ok; + const QPointF point = QtUtils::toPoint(value, &ok); + if (ok) return point; + const QRectF rect = QtUtils::toRect(value, &ok); + if (ok) return rect; + const float f = value.toFloat(&ok); + if (ok) return f; + return value; +} + void File::set(const QString &key, const QVariant &value) { if (key == "Label") { @@ -145,35 +157,16 @@ void File::set(const QString &key, const QVariant &value) m_metadata.insert(key, value); } -// Note that we assume all values within a parameter list are the same type void File::set(const QString &key, const QString &value) { - if (value[0] == '[') /* QVariantList */ { - QStringList values = value.mid(1, value.size()-2).split(", "); + if (value.startsWith('[') && value.endsWith(']')) { QList variants; - if (values[0][0] == '(') /* List of Points or Rects */ { - if (values[0].split(',').size() == 2) /* List of Points */ foreach(const QString &word, values) variants.append(QtUtils::toPoint(word)); - else if (values[0].split(',').size() == 4) /* List of Rects */ foreach(const QString &word, values) variants.append(QtUtils::toRect(word)); - else qFatal("Incorrect landmark format."); - } - else { - bool ok; - foreach(const QString &word, values) { - variants.append(word.toFloat(&ok)); - if (!ok) { - m_metadata.insert(key, value.split(", ")); - return; - } - } - } - m_metadata.insert(key, variants); - } - else if (value[0] == '(') /* Point or Rect */ { - if (value.split(',').size() == 2) /* QPointF */ m_metadata.insert(key, QtUtils::toPoint(value)); - else if (value.split(',').size() == 4) /* QRectF */ m_metadata.insert(key, QtUtils::toRect(value)); - else qFatal("Incorrect landmark format."); + foreach (const QString &value, QtUtils::parse(value.mid(1, value.size()-2))) + variants.append(parse(value)); + set(key, QVariant(variants)); + } else { + set(key, QVariant(parse(value))); } - else m_metadata.insert(key, value); } bool File::getBool(const QString &key, bool defaultValue) const @@ -294,7 +287,7 @@ void File::init(const QString &file) if (unnamed) setParameter(i, words[0]); else set(words[0], QVariant()); } else { - set(words[0],words[1]); + set(words[0], words[1]); } } name = name.left(index); diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index e7a03a3..2775aee 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -194,6 +194,7 @@ struct BR_EXPORT File bool contains(const QString &key) const; /*!< \brief Returns \c true if the key has an associated value, \c false otherwise. */ QVariant value(const QString &key) const; /*!< \brief Returns the value for the specified key. */ + static QVariant parse(const QString &value); /*!< \brief Try to convert the QString to a QPointF or QRectF if possible. */ void set(const QString &key, const QVariant &value); /*!< \brief Insert or overwrite the metadata key with the specified value. */ void set(const QString &key, const QString &value); /*!< \brief Insert or overwrite the metadata key with the specified value. */ inline void remove(const QString &key) { m_metadata.remove(key); } /*!< \brief Remove the metadata key. */ diff --git a/openbr/plugins/misc.cpp b/openbr/plugins/misc.cpp index dc62225..f84e7ea 100644 --- a/openbr/plugins/misc.cpp +++ b/openbr/plugins/misc.cpp @@ -14,6 +14,7 @@ * limitations under the License. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#include #include #include "openbr_internal.h" #include "openbr/core/opencvutils.h" @@ -399,6 +400,29 @@ class AsTransform : public UntrainableMetaTransform BR_REGISTER(Transform, AsTransform) +/*! + * \ingroup transforms + * \brief Change the template label using a regular expresion matched to the file's base name. + */ +class RelabelTransform : public UntrainableMetaTransform +{ + Q_OBJECT + Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false) + BR_PROPERTY(QString, regexp, "") + + void project(const Template &src, Template &dst) const + { + dst = src; + QRegularExpression re(regexp); + QRegularExpressionMatch match = re.match(dst.file.baseName()); + if (!match.hasMatch()) + qFatal("Unable to match regular expression \"%s\" to base name \"%s\"!", qPrintable(regexp), qPrintable(dst.file.baseName())); + dst.file.set("Label", match.captured(match.lastCapturedIndex())); + } +}; + +BR_REGISTER(Transform, RelabelTransform) + } #include "misc.moc"