Commit aa5961835a36c6a9c38dbf1a83ef67bb958ffd33
1 parent
87f7a91f
Fixed file.flat() and file.init() to work with points and rects. other minor bug fixes
Showing
8 changed files
with
139 additions
and
34 deletions
openbr/openbr_plugin.cpp
| @@ -43,6 +43,9 @@ using namespace br; | @@ -43,6 +43,9 @@ using namespace br; | ||
| 43 | using namespace cv; | 43 | using namespace cv; |
| 44 | 44 | ||
| 45 | /* File - public methods */ | 45 | /* File - public methods */ |
| 46 | +// Note that the convention for displaying metadata is as follows: | ||
| 47 | +// [] for lists in which argument order does not matter (e.g. [FTO=false, Index=0]), | ||
| 48 | +// () for lists in which argument order matters (e.g. First_Eye(100.0,100.0)). | ||
| 46 | QString File::flat() const | 49 | QString File::flat() const |
| 47 | { | 50 | { |
| 48 | QStringList values; | 51 | QStringList values; |
| @@ -51,18 +54,14 @@ QString File::flat() const | @@ -51,18 +54,14 @@ QString File::flat() const | ||
| 51 | const QVariant value = this->value(key); | 54 | const QVariant value = this->value(key); |
| 52 | if (value.isNull()) values.append(key); | 55 | if (value.isNull()) values.append(key); |
| 53 | else { | 56 | else { |
| 54 | - if (value.canConvert(QVariant::String)) { | ||
| 55 | - values.append(key + "=" + value.toString()); | ||
| 56 | - } | ||
| 57 | - else { | ||
| 58 | - if (value.canConvert(QVariant::PointF)) values.append(key + "=" + QString("(%1,%2)").arg(QString::number(qvariant_cast<QPointF>(value).x()), | ||
| 59 | - QString::number(qvariant_cast<QPointF>(value).y()))); | ||
| 60 | - else if (value.canConvert(QVariant::RectF)) values.append(key + "=" + QString("(%1,%2,%3,%4)").arg(QString::number(qvariant_cast<QRectF>(value).x()), | ||
| 61 | - QString::number(qvariant_cast<QRectF>(value).y()), | ||
| 62 | - QString::number(qvariant_cast<QRectF>(value).width()), | ||
| 63 | - QString::number(qvariant_cast<QRectF>(value).height()))); | ||
| 64 | - else values.append(key + "="); | 57 | + if (QString(value.typeName()) == "QVariantList") { |
| 58 | + QStringList landmarks; | ||
| 59 | + foreach(const QVariant &landmark, qvariant_cast<QVariantList>(value)) { | ||
| 60 | + landmarks.append(toString(landmark)); | ||
| 61 | + } | ||
| 62 | + if (!landmarks.isEmpty()) values.append(key + "=[" + landmarks.join(", ") + "]"); | ||
| 65 | } | 63 | } |
| 64 | + else values.append(key + "=" + toString(value)); | ||
| 66 | } | 65 | } |
| 67 | } | 66 | } |
| 68 | 67 | ||
| @@ -266,26 +265,49 @@ void File::init(const QString &file) | @@ -266,26 +265,49 @@ void File::init(const QString &file) | ||
| 266 | if (unnamed) setParameter(i, words[0]); | 265 | if (unnamed) setParameter(i, words[0]); |
| 267 | else set(words[0], QVariant()); | 266 | else set(words[0], QVariant()); |
| 268 | } else { | 267 | } else { |
| 269 | - if (words[1][0] == '(') { | ||
| 270 | - QStringList values = words[1].split(','); | ||
| 271 | - if (values.size() == 2) /* QPointF */ { | ||
| 272 | - values[1].chop(1); | ||
| 273 | - QPointF point(values[0].mid(1).toFloat(), values[1].remove(')').toFloat()); | ||
| 274 | - set(words[0], point); | ||
| 275 | - } | ||
| 276 | - else /* QRectF */ { | ||
| 277 | - values[3].chop(1); | ||
| 278 | - QRectF rect(values[0].mid(1).toFloat(), values[1].toFloat(), values[2].toFloat(), values[3].remove(')').toFloat()); | ||
| 279 | - set(words[0], rect); | ||
| 280 | - } | ||
| 281 | - } | ||
| 282 | - else set(words[0], words[1]); | 268 | + fromString(words[0],words[1]); |
| 283 | } | 269 | } |
| 284 | } | 270 | } |
| 285 | name = name.left(index); | 271 | name = name.left(index); |
| 286 | } | 272 | } |
| 287 | } | 273 | } |
| 288 | 274 | ||
| 275 | +QString File::toString(const QVariant &variant) const | ||
| 276 | +{ | ||
| 277 | + if (variant.canConvert(QVariant::String)) return variant.toString(); | ||
| 278 | + else if(variant.canConvert(QVariant::PointF)) return QString("(%1,%2)").arg(QString::number(qvariant_cast<QPointF>(variant).x()), | ||
| 279 | + QString::number(qvariant_cast<QPointF>(variant).y())); | ||
| 280 | + else if (variant.canConvert(QVariant::RectF)) return QString("(%1,%2,%3,%4)").arg(QString::number(qvariant_cast<QRectF>(variant).x()), | ||
| 281 | + QString::number(qvariant_cast<QRectF>(variant).y()), | ||
| 282 | + QString::number(qvariant_cast<QRectF>(variant).width()), | ||
| 283 | + QString::number(qvariant_cast<QRectF>(variant).height())); | ||
| 284 | + return QString(); | ||
| 285 | +} | ||
| 286 | + | ||
| 287 | +void File::fromString(const QString &key, const QString &value) | ||
| 288 | +{ | ||
| 289 | + if (value[0] == '[') /* QVariantList */ { | ||
| 290 | + QStringList values = value.mid(1, value.size()-2).split(", "); | ||
| 291 | + foreach(const QString &word, values) fromString(key, word); | ||
| 292 | + } | ||
| 293 | + else if (value[0] == '(') { | ||
| 294 | + QStringList values = value.split(','); | ||
| 295 | + if (values.size() == 2) /* QPointF */ { | ||
| 296 | + values[1].chop(1); | ||
| 297 | + QPointF point(values[0].mid(1).toFloat(), values[1].toFloat()); | ||
| 298 | + if (key != "Points") set(key, point); | ||
| 299 | + else appendPoint(point); | ||
| 300 | + } | ||
| 301 | + else /* QRectF */ { | ||
| 302 | + values[3].chop(1); | ||
| 303 | + QRectF rect(values[0].mid(1).toFloat(), values[1].toFloat(), values[2].toFloat(), values[3].toFloat()); | ||
| 304 | + if (key != "Rects") set(key, rect); | ||
| 305 | + else appendRect(rect); | ||
| 306 | + } | ||
| 307 | + } | ||
| 308 | + else set(key, value); | ||
| 309 | +} | ||
| 310 | + | ||
| 289 | /* File - global methods */ | 311 | /* File - global methods */ |
| 290 | QDebug br::operator<<(QDebug dbg, const File &file) | 312 | QDebug br::operator<<(QDebug dbg, const File &file) |
| 291 | { | 313 | { |
openbr/openbr_plugin.h
| @@ -245,6 +245,8 @@ private: | @@ -245,6 +245,8 @@ private: | ||
| 245 | BR_EXPORT friend QDataStream &operator>>(QDataStream &stream, File &file); | 245 | BR_EXPORT friend QDataStream &operator>>(QDataStream &stream, File &file); |
| 246 | 246 | ||
| 247 | void init(const QString &file); | 247 | void init(const QString &file); |
| 248 | + QString toString(const QVariant &variant) const; | ||
| 249 | + void fromString(const QString &key, const QString &value); | ||
| 248 | }; | 250 | }; |
| 249 | 251 | ||
| 250 | BR_EXPORT QDebug operator<<(QDebug dbg, const File &file); /*!< \brief Prints br::File::flat() to \c stderr. */ | 252 | BR_EXPORT QDebug operator<<(QDebug dbg, const File &file); /*!< \brief Prints br::File::flat() to \c stderr. */ |
openbr/plugins/distance.cpp
| @@ -177,6 +177,37 @@ class PipeDistance : public Distance | @@ -177,6 +177,37 @@ class PipeDistance : public Distance | ||
| 177 | 177 | ||
| 178 | BR_REGISTER(Distance, PipeDistance) | 178 | BR_REGISTER(Distance, PipeDistance) |
| 179 | 179 | ||
| 180 | +class AverageDistance : public Distance | ||
| 181 | +{ | ||
| 182 | + Q_OBJECT | ||
| 183 | + Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false) | ||
| 184 | + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)")) | ||
| 185 | + | ||
| 186 | + void train(const TemplateList &src) | ||
| 187 | + { | ||
| 188 | + distance->train(src); | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + float compare(const Template &a, const Template &b) const | ||
| 192 | + { | ||
| 193 | + if (a.size() != b.size()) | ||
| 194 | + qDebug() << a.size() << " " << b.size(); | ||
| 195 | + | ||
| 196 | + float score = 0; | ||
| 197 | + | ||
| 198 | + for (int i = 0; i < a.size(); i++) { | ||
| 199 | + //Template | ||
| 200 | + score += distance->compare(a[i],b[i]); | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + qDebug() << score; | ||
| 204 | + | ||
| 205 | + return score; | ||
| 206 | + } | ||
| 207 | +}; | ||
| 208 | + | ||
| 209 | +BR_REGISTER(Distance, AverageDistance) | ||
| 210 | + | ||
| 180 | /*! | 211 | /*! |
| 181 | * \ingroup distances | 212 | * \ingroup distances |
| 182 | * \brief Fast 8-bit L1 distance | 213 | * \brief Fast 8-bit L1 distance |
openbr/plugins/gallery.cpp
| @@ -302,6 +302,8 @@ class memGallery : public Gallery | @@ -302,6 +302,8 @@ class memGallery : public Gallery | ||
| 302 | 302 | ||
| 303 | static void align(TemplateList &templates) | 303 | static void align(TemplateList &templates) |
| 304 | { | 304 | { |
| 305 | + //if (templates[0].size() > 1) return; | ||
| 306 | + | ||
| 305 | bool uniform = true; | 307 | bool uniform = true; |
| 306 | QVector<uchar> alignedData(templates.bytes<size_t>()); | 308 | QVector<uchar> alignedData(templates.bytes<size_t>()); |
| 307 | size_t offset = 0; | 309 | size_t offset = 0; |
openbr/plugins/misc.cpp
| @@ -322,6 +322,54 @@ BR_REGISTER(Transform, RenameFirstTransform) | @@ -322,6 +322,54 @@ BR_REGISTER(Transform, RenameFirstTransform) | ||
| 322 | 322 | ||
| 323 | /*! | 323 | /*! |
| 324 | * \ingroup transforms | 324 | * \ingroup transforms |
| 325 | + * \brief Name a point | ||
| 326 | + * \author Scott Klum \cite sklum | ||
| 327 | + */ | ||
| 328 | +class LabelTransform : public UntrainableMetaTransform | ||
| 329 | +{ | ||
| 330 | + Q_OBJECT | ||
| 331 | + Q_PROPERTY(QList<int> points READ get_points WRITE set_points RESET reset_points STORED false) | ||
| 332 | + Q_PROPERTY(QStringList names READ get_names WRITE set_names RESET reset_names STORED false) | ||
| 333 | + BR_PROPERTY(QList<int>, points, QList<int>()) | ||
| 334 | + BR_PROPERTY(QStringList, names, QStringList()) | ||
| 335 | + | ||
| 336 | + void project(const Template &src, Template &dst) const | ||
| 337 | + { | ||
| 338 | + if (points.size() != names.size()) qFatal("Point/name size mismatch"); | ||
| 339 | + | ||
| 340 | + dst = src; | ||
| 341 | + | ||
| 342 | + for (int i=0; i<points.size(); i++) | ||
| 343 | + dst.file.set(names[i], points[i]); | ||
| 344 | + } | ||
| 345 | +}; | ||
| 346 | + | ||
| 347 | +BR_REGISTER(Transform, LabelTransform) | ||
| 348 | + | ||
| 349 | +/*! | ||
| 350 | + * \ingroup transforms | ||
| 351 | + * \brief Name a point | ||
| 352 | + * \author Scott Klum \cite sklum | ||
| 353 | + */ | ||
| 354 | +class AnonymizeTransform : public UntrainableMetaTransform | ||
| 355 | +{ | ||
| 356 | + Q_OBJECT | ||
| 357 | + Q_PROPERTY(QStringList names READ get_names WRITE set_names RESET reset_names STORED false) | ||
| 358 | + BR_PROPERTY(QStringList, names, QStringList()) | ||
| 359 | + | ||
| 360 | + void project(const Template &src, Template &dst) const | ||
| 361 | + { | ||
| 362 | + dst = src; | ||
| 363 | + | ||
| 364 | + foreach (const QString &name, names) | ||
| 365 | + if (src.file.contains(name)) dst.file.appendPoint(src.file.get<QPointF>(name)); | ||
| 366 | + } | ||
| 367 | +}; | ||
| 368 | + | ||
| 369 | +BR_REGISTER(Transform, AnonymizeTransform) | ||
| 370 | + | ||
| 371 | +/*! | ||
| 372 | + * \ingroup transforms | ||
| 325 | * \brief Change the br::Template::file extension | 373 | * \brief Change the br::Template::file extension |
| 326 | * \author Josh Klontz \cite jklontz | 374 | * \author Josh Klontz \cite jklontz |
| 327 | */ | 375 | */ |
openbr/plugins/pp5.cpp
openbr/plugins/regions.cpp
| @@ -157,7 +157,7 @@ BR_REGISTER(Transform, DupTransform) | @@ -157,7 +157,7 @@ BR_REGISTER(Transform, DupTransform) | ||
| 157 | * \todo Padding should be a percent of total image size | 157 | * \todo Padding should be a percent of total image size |
| 158 | */ | 158 | */ |
| 159 | 159 | ||
| 160 | -class RectFromLandmarksTransform : public UntrainableTransform | 160 | +class RectFromPointsTransform : public UntrainableTransform |
| 161 | { | 161 | { |
| 162 | Q_OBJECT | 162 | Q_OBJECT |
| 163 | Q_PROPERTY(QList<int> indices READ get_indices WRITE set_indices RESET reset_indices STORED false) | 163 | Q_PROPERTY(QList<int> indices READ get_indices WRITE set_indices RESET reset_indices STORED false) |
| @@ -181,7 +181,7 @@ class RectFromLandmarksTransform : public UntrainableTransform | @@ -181,7 +181,7 @@ class RectFromLandmarksTransform : public UntrainableTransform | ||
| 181 | maxX = maxY = -std::numeric_limits<int>::max(); | 181 | maxX = maxY = -std::numeric_limits<int>::max(); |
| 182 | 182 | ||
| 183 | foreach(int index, indices) { | 183 | foreach(int index, indices) { |
| 184 | - if (src.file.points().size() > index+1) { | 184 | + if (src.file.points().size() > index) { |
| 185 | if (src.file.points()[index].x() < minX) minX = src.file.points()[index].x(); | 185 | if (src.file.points()[index].x() < minX) minX = src.file.points()[index].x(); |
| 186 | if (src.file.points()[index].x() > maxX) maxX = src.file.points()[index].x(); | 186 | if (src.file.points()[index].x() > maxX) maxX = src.file.points()[index].x(); |
| 187 | if (src.file.points()[index].y() < minY) minY = src.file.points()[index].y(); | 187 | if (src.file.points()[index].y() < minY) minY = src.file.points()[index].y(); |
| @@ -203,7 +203,7 @@ class RectFromLandmarksTransform : public UntrainableTransform | @@ -203,7 +203,7 @@ class RectFromLandmarksTransform : public UntrainableTransform | ||
| 203 | } | 203 | } |
| 204 | }; | 204 | }; |
| 205 | 205 | ||
| 206 | -BR_REGISTER(Transform, RectFromLandmarksTransform) | 206 | +BR_REGISTER(Transform, RectFromPointsTransform) |
| 207 | 207 | ||
| 208 | } // namespace br | 208 | } // namespace br |
| 209 | 209 |
openbr/plugins/stasm.cpp
| @@ -18,11 +18,11 @@ class StasmInitializer : public Initializer | @@ -18,11 +18,11 @@ class StasmInitializer : public Initializer | ||
| 18 | 18 | ||
| 19 | void initialize() const | 19 | void initialize() const |
| 20 | { | 20 | { |
| 21 | - Globals->abbreviations.insert("RectFromStasmEyes","RectFromLandmarks([27, 28, 29, 30, 31, 32, 33, 34, 35, 36],0.125,6.0)+Resize(44,164)"); // | ||
| 22 | - Globals->abbreviations.insert("RectFromStasmJaw","RectFromLandmarks([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],10)"); | ||
| 23 | - Globals->abbreviations.insert("RectFromStasmBrow","RectFromLandmarks([15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26],0.25,6.5)+Resize(44,230)"); | ||
| 24 | - Globals->abbreviations.insert("RectFromStasmNose","RectFromLandmarks([38, 39, 40, 41, 42, 43, 44, 67],0.1,1.5)+Resize(44,44)"); | ||
| 25 | - Globals->abbreviations.insert("RectFromStasmMouth","RectFromLandmarks([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66],0.3,3.0)+Resize(44,110)"); | 21 | + Globals->abbreviations.insert("RectFromStasmEyes","RectFromPoints([27, 28, 29, 30, 31, 32, 33, 34, 35, 36],0.125,6.0)+Resize(44,164)"); // |
| 22 | + Globals->abbreviations.insert("RectFromStasmJaw","RectFromPoints([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],10)"); | ||
| 23 | + Globals->abbreviations.insert("RectFromStasmBrow","RectFromPoints([15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26],0.25,6.5)+Resize(44,230)"); | ||
| 24 | + Globals->abbreviations.insert("RectFromStasmNose","RectFromPoints([38, 39, 40, 41, 42, 43, 44, 67],0.1,1.5)+Resize(44,44)"); | ||
| 25 | + Globals->abbreviations.insert("RectFromStasmMouth","RectFromPoints([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66],0.3,3.0)+Resize(44,110)"); | ||
| 26 | } | 26 | } |
| 27 | }; | 27 | }; |
| 28 | 28 |