Commit 0645316a10983c3b3a1ca67aca9edc9f2e8ead37
Merge branch 'master' of https://github.com/biometrics/openbr
Showing
5 changed files
with
78 additions
and
40 deletions
openbr/core/qtutils.cpp
| ... | ... | @@ -285,25 +285,45 @@ void QtUtils::checkArgsSize(const QString &name, const QStringList &args, int mi |
| 285 | 285 | if (args.size() > max) qFatal("%s expects no more than %d arguments, got %d", qPrintable(name), max, args.size()); |
| 286 | 286 | } |
| 287 | 287 | |
| 288 | -QPointF QtUtils::toPoint(const QString &string) | |
| 288 | +QPointF QtUtils::toPoint(const QString &string, bool *ok) | |
| 289 | 289 | { |
| 290 | - QStringList values = string.split(','); | |
| 291 | - if (values.size() == 2) { | |
| 292 | - values[1].chop(1); | |
| 293 | - return QPointF(values[0].mid(1).toFloat(), values[1].toFloat()); | |
| 290 | + if (string.startsWith('(') && string.endsWith(')')) { | |
| 291 | + const QStringList words = parse(string.mid(1, string.size()-2)); | |
| 292 | + if (words.size() == 2) { | |
| 293 | + float x, y; | |
| 294 | + bool okX, okY; | |
| 295 | + x = words[0].toFloat(&okX); | |
| 296 | + y = words[1].toFloat(&okY); | |
| 297 | + if (okX && okY) { | |
| 298 | + if (ok) *ok = true; | |
| 299 | + return QPointF(x, y); | |
| 300 | + } | |
| 301 | + } | |
| 294 | 302 | } |
| 295 | - else qFatal("Failed to convert %s to QPointF format.", qPrintable(string)); | |
| 303 | + | |
| 304 | + if (ok) *ok = false; | |
| 296 | 305 | return QPointF(); |
| 297 | 306 | } |
| 298 | 307 | |
| 299 | -QRectF QtUtils::toRect(const QString &string) | |
| 308 | +QRectF QtUtils::toRect(const QString &string, bool *ok) | |
| 300 | 309 | { |
| 301 | - QStringList values = string.split(','); | |
| 302 | - if (values.size() == 4) { | |
| 303 | - values[3].chop(1); | |
| 304 | - return QRectF(values[0].mid(1).toFloat(), values[1].toFloat(), values[2].toFloat(), values[3].toFloat()); | |
| 310 | + if (string.startsWith('(') && string.endsWith(')')) { | |
| 311 | + const QStringList words = parse(string.mid(1, string.size()-2)); | |
| 312 | + if (words.size() == 4) { | |
| 313 | + float x, y, width, height; | |
| 314 | + bool okX, okY, okWidth, okHeight; | |
| 315 | + x = words[0].toFloat(&okX); | |
| 316 | + y = words[1].toFloat(&okY); | |
| 317 | + width = words[0].toFloat(&okWidth); | |
| 318 | + height = words[1].toFloat(&okHeight); | |
| 319 | + if (okX && okY && okWidth && okHeight) { | |
| 320 | + if (ok) *ok = true; | |
| 321 | + return QRectF(x, y, width, height); | |
| 322 | + } | |
| 323 | + } | |
| 305 | 324 | } |
| 306 | - else qFatal("Failed to convert %s to QRectF format.", qPrintable(string)); | |
| 325 | + | |
| 326 | + if (ok) *ok = false; | |
| 307 | 327 | return QRectF(); |
| 308 | 328 | } |
| 309 | 329 | ... | ... |
openbr/core/qtutils.h
| ... | ... | @@ -62,8 +62,8 @@ namespace QtUtils |
| 62 | 62 | QString shortTextHash(QString string); |
| 63 | 63 | QStringList parse(QString args, char split = ','); |
| 64 | 64 | void checkArgsSize(const QString &name, const QStringList &args, int min, int max); |
| 65 | - QPointF toPoint(const QString &string); | |
| 66 | - QRectF toRect(const QString &string); | |
| 65 | + QPointF toPoint(const QString &string, bool *ok = NULL); | |
| 66 | + QRectF toRect(const QString &string, bool *ok = NULL); | |
| 67 | 67 | |
| 68 | 68 | /**** Process Utilities ****/ |
| 69 | 69 | bool runRScript(const QString &file); | ... | ... |
openbr/openbr_plugin.cpp
| ... | ... | @@ -125,6 +125,18 @@ QVariant File::value(const QString &key) const |
| 125 | 125 | return m_metadata.contains(key) ? m_metadata.value(key) : Globals->property(qPrintable(key)); |
| 126 | 126 | } |
| 127 | 127 | |
| 128 | +QVariant File::parse(const QString &value) | |
| 129 | +{ | |
| 130 | + bool ok; | |
| 131 | + const QPointF point = QtUtils::toPoint(value, &ok); | |
| 132 | + if (ok) return point; | |
| 133 | + const QRectF rect = QtUtils::toRect(value, &ok); | |
| 134 | + if (ok) return rect; | |
| 135 | + const float f = value.toFloat(&ok); | |
| 136 | + if (ok) return f; | |
| 137 | + return value; | |
| 138 | +} | |
| 139 | + | |
| 128 | 140 | void File::set(const QString &key, const QVariant &value) |
| 129 | 141 | { |
| 130 | 142 | if (key == "Label") { |
| ... | ... | @@ -145,35 +157,16 @@ void File::set(const QString &key, const QVariant &value) |
| 145 | 157 | m_metadata.insert(key, value); |
| 146 | 158 | } |
| 147 | 159 | |
| 148 | -// Note that we assume all values within a parameter list are the same type | |
| 149 | 160 | void File::set(const QString &key, const QString &value) |
| 150 | 161 | { |
| 151 | - if (value[0] == '[') /* QVariantList */ { | |
| 152 | - QStringList values = value.mid(1, value.size()-2).split(", "); | |
| 162 | + if (value.startsWith('[') && value.endsWith(']')) { | |
| 153 | 163 | QList<QVariant> variants; |
| 154 | - if (values[0][0] == '(') /* List of Points or Rects */ { | |
| 155 | - if (values[0].split(',').size() == 2) /* List of Points */ foreach(const QString &word, values) variants.append(QtUtils::toPoint(word)); | |
| 156 | - else if (values[0].split(',').size() == 4) /* List of Rects */ foreach(const QString &word, values) variants.append(QtUtils::toRect(word)); | |
| 157 | - else qFatal("Incorrect landmark format."); | |
| 158 | - } | |
| 159 | - else { | |
| 160 | - bool ok; | |
| 161 | - foreach(const QString &word, values) { | |
| 162 | - variants.append(word.toFloat(&ok)); | |
| 163 | - if (!ok) { | |
| 164 | - m_metadata.insert(key, value.split(", ")); | |
| 165 | - return; | |
| 166 | - } | |
| 167 | - } | |
| 168 | - } | |
| 169 | - m_metadata.insert(key, variants); | |
| 170 | - } | |
| 171 | - else if (value[0] == '(') /* Point or Rect */ { | |
| 172 | - if (value.split(',').size() == 2) /* QPointF */ m_metadata.insert(key, QtUtils::toPoint(value)); | |
| 173 | - else if (value.split(',').size() == 4) /* QRectF */ m_metadata.insert(key, QtUtils::toRect(value)); | |
| 174 | - else qFatal("Incorrect landmark format."); | |
| 164 | + foreach (const QString &value, QtUtils::parse(value.mid(1, value.size()-2))) | |
| 165 | + variants.append(parse(value)); | |
| 166 | + set(key, QVariant(variants)); | |
| 167 | + } else { | |
| 168 | + set(key, QVariant(parse(value))); | |
| 175 | 169 | } |
| 176 | - else m_metadata.insert(key, value); | |
| 177 | 170 | } |
| 178 | 171 | |
| 179 | 172 | bool File::getBool(const QString &key, bool defaultValue) const |
| ... | ... | @@ -294,7 +287,7 @@ void File::init(const QString &file) |
| 294 | 287 | if (unnamed) setParameter(i, words[0]); |
| 295 | 288 | else set(words[0], QVariant()); |
| 296 | 289 | } else { |
| 297 | - set(words[0],words[1]); | |
| 290 | + set(words[0], words[1]); | |
| 298 | 291 | } |
| 299 | 292 | } |
| 300 | 293 | name = name.left(index); | ... | ... |
openbr/openbr_plugin.h
| ... | ... | @@ -194,6 +194,7 @@ struct BR_EXPORT File |
| 194 | 194 | |
| 195 | 195 | bool contains(const QString &key) const; /*!< \brief Returns \c true if the key has an associated value, \c false otherwise. */ |
| 196 | 196 | QVariant value(const QString &key) const; /*!< \brief Returns the value for the specified key. */ |
| 197 | + static QVariant parse(const QString &value); /*!< \brief Try to convert the QString to a QPointF or QRectF if possible. */ | |
| 197 | 198 | void set(const QString &key, const QVariant &value); /*!< \brief Insert or overwrite the metadata key with the specified value. */ |
| 198 | 199 | void set(const QString &key, const QString &value); /*!< \brief Insert or overwrite the metadata key with the specified value. */ |
| 199 | 200 | inline void remove(const QString &key) { m_metadata.remove(key); } /*!< \brief Remove the metadata key. */ | ... | ... |
openbr/plugins/misc.cpp
| ... | ... | @@ -14,6 +14,7 @@ |
| 14 | 14 | * limitations under the License. * |
| 15 | 15 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
| 16 | 16 | |
| 17 | +#include <QRegularExpression> | |
| 17 | 18 | #include <opencv2/highgui/highgui.hpp> |
| 18 | 19 | #include "openbr_internal.h" |
| 19 | 20 | #include "openbr/core/opencvutils.h" |
| ... | ... | @@ -399,6 +400,29 @@ class AsTransform : public UntrainableMetaTransform |
| 399 | 400 | |
| 400 | 401 | BR_REGISTER(Transform, AsTransform) |
| 401 | 402 | |
| 403 | +/*! | |
| 404 | + * \ingroup transforms | |
| 405 | + * \brief Change the template label using a regular expresion matched to the file's base name. | |
| 406 | + */ | |
| 407 | +class RelabelTransform : public UntrainableMetaTransform | |
| 408 | +{ | |
| 409 | + Q_OBJECT | |
| 410 | + Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false) | |
| 411 | + BR_PROPERTY(QString, regexp, "") | |
| 412 | + | |
| 413 | + void project(const Template &src, Template &dst) const | |
| 414 | + { | |
| 415 | + dst = src; | |
| 416 | + QRegularExpression re(regexp); | |
| 417 | + QRegularExpressionMatch match = re.match(dst.file.baseName()); | |
| 418 | + if (!match.hasMatch()) | |
| 419 | + qFatal("Unable to match regular expression \"%s\" to base name \"%s\"!", qPrintable(regexp), qPrintable(dst.file.baseName())); | |
| 420 | + dst.file.set("Label", match.captured(match.lastCapturedIndex())); | |
| 421 | + } | |
| 422 | +}; | |
| 423 | + | |
| 424 | +BR_REGISTER(Transform, RelabelTransform) | |
| 425 | + | |
| 402 | 426 | } |
| 403 | 427 | |
| 404 | 428 | #include "misc.moc" | ... | ... |