Commit 31e9234bf378e99a3311e70122635a530a496966
Merge branch 'master' into janus
Showing
9 changed files
with
94 additions
and
52 deletions
openbr/core/core.cpp
| @@ -45,7 +45,8 @@ struct AlgorithmCore | @@ -45,7 +45,8 @@ struct AlgorithmCore | ||
| 45 | qDebug("Training on %s%s", qPrintable(input.flat()), | 45 | qDebug("Training on %s%s", qPrintable(input.flat()), |
| 46 | model.isEmpty() ? "" : qPrintable(" to " + model)); | 46 | model.isEmpty() ? "" : qPrintable(" to " + model)); |
| 47 | 47 | ||
| 48 | - QScopedPointer<Transform> trainingWrapper(Transform::make("DirectStream([Identity])", NULL)); | 48 | + QScopedPointer<Transform> trainingWrapper(Transform::make("DirectStream([Identity], readMode=DistributeFrames)", NULL)); |
| 49 | + | ||
| 49 | CompositeTransform * downcast = dynamic_cast<CompositeTransform *>(trainingWrapper.data()); | 50 | CompositeTransform * downcast = dynamic_cast<CompositeTransform *>(trainingWrapper.data()); |
| 50 | if (downcast == NULL) | 51 | if (downcast == NULL) |
| 51 | qFatal("downcast failed?"); | 52 | qFatal("downcast failed?"); |
| @@ -70,7 +71,7 @@ struct AlgorithmCore | @@ -70,7 +71,7 @@ struct AlgorithmCore | ||
| 70 | 71 | ||
| 71 | if (!distance.isNull()) { | 72 | if (!distance.isNull()) { |
| 72 | qDebug("Projecting Enrollment"); | 73 | qDebug("Projecting Enrollment"); |
| 73 | - data >> *downcast; | 74 | + downcast->projectUpdate(data,data); |
| 74 | 75 | ||
| 75 | qDebug("Training Comparison"); | 76 | qDebug("Training Comparison"); |
| 76 | distance->train(data); | 77 | distance->train(data); |
openbr/openbr.cpp
| @@ -353,6 +353,17 @@ void br_set_filename(br_template tmpl, const char *filename) | @@ -353,6 +353,17 @@ void br_set_filename(br_template tmpl, const char *filename) | ||
| 353 | t->file.name = filename; | 353 | t->file.name = filename; |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | +const char* br_get_metadata_string(br_template tmpl, const char *key) | ||
| 357 | +{ | ||
| 358 | + Template *t = reinterpret_cast<Template*>(tmpl); | ||
| 359 | + // need an object outside of this scope | ||
| 360 | + // so the char pointer is valid | ||
| 361 | + static QByteArray result; | ||
| 362 | + QVariant qvar = t->file.value(key); | ||
| 363 | + result = QtUtils::toString(qvar).toUtf8(); | ||
| 364 | + return result.data(); | ||
| 365 | +} | ||
| 366 | + | ||
| 356 | br_template_list br_enroll_template(br_template tmpl) | 367 | br_template_list br_enroll_template(br_template tmpl) |
| 357 | { | 368 | { |
| 358 | Template *t = reinterpret_cast<Template*>(tmpl); | 369 | Template *t = reinterpret_cast<Template*>(tmpl); |
openbr/openbr.h
| @@ -475,6 +475,10 @@ BR_EXPORT bool br_img_is_empty(br_template tmpl); | @@ -475,6 +475,10 @@ BR_EXPORT bool br_img_is_empty(br_template tmpl); | ||
| 475 | */ | 475 | */ |
| 476 | BR_EXPORT void br_set_filename(br_template tmpl, const char *filename); | 476 | BR_EXPORT void br_set_filename(br_template tmpl, const char *filename); |
| 477 | /*! | 477 | /*! |
| 478 | + * \brief Get metadata as a string for the given key in the given template. | ||
| 479 | + */ | ||
| 480 | +BR_EXPORT const char* br_get_metadata_string(br_template, const char *key); | ||
| 481 | +/*! | ||
| 478 | * \brief Enroll a br::Template from the C API! Returns a pointer to a br::TemplateList | 482 | * \brief Enroll a br::Template from the C API! Returns a pointer to a br::TemplateList |
| 479 | * \param tmpl Pointer to a br::Template. | 483 | * \param tmpl Pointer to a br::Template. |
| 480 | */ | 484 | */ |
openbr/openbr_plugin.cpp
| @@ -550,20 +550,18 @@ QStringList Object::parameters() const | @@ -550,20 +550,18 @@ QStringList Object::parameters() const | ||
| 550 | 550 | ||
| 551 | for (int i = firstAvailablePropertyIdx; i < metaObject()->propertyCount();i++) { | 551 | for (int i = firstAvailablePropertyIdx; i < metaObject()->propertyCount();i++) { |
| 552 | QMetaProperty property = metaObject()->property(i); | 552 | QMetaProperty property = metaObject()->property(i); |
| 553 | - if (property.isStored(this)) continue; | ||
| 554 | parameters.append(QString("%1 %2 = %3").arg(property.typeName(), property.name(), property.read(this).toString())); | 553 | parameters.append(QString("%1 %2 = %3").arg(property.typeName(), property.name(), property.read(this).toString())); |
| 555 | } | 554 | } |
| 555 | + | ||
| 556 | return parameters; | 556 | return parameters; |
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | QStringList Object::arguments() const | 559 | QStringList Object::arguments() const |
| 560 | { | 560 | { |
| 561 | QStringList arguments; | 561 | QStringList arguments; |
| 562 | - for (int i=metaObject()->propertyOffset(); i<metaObject()->propertyCount(); i++) { | ||
| 563 | - QMetaProperty property = metaObject()->property(i); | ||
| 564 | - if (property.isStored(this)) continue; | 562 | + for (int i=metaObject()->propertyOffset(); i<metaObject()->propertyCount(); i++) |
| 565 | arguments.append(argument(i)); | 563 | arguments.append(argument(i)); |
| 566 | - } | 564 | + |
| 567 | return arguments; | 565 | return arguments; |
| 568 | } | 566 | } |
| 569 | 567 | ||
| @@ -705,7 +703,14 @@ void Object::setProperty(const QString &name, QVariant value) | @@ -705,7 +703,14 @@ void Object::setProperty(const QString &name, QVariant value) | ||
| 705 | int index = metaObject()->indexOfProperty(qPrintable(name)); | 703 | int index = metaObject()->indexOfProperty(qPrintable(name)); |
| 706 | if (index != -1) type = metaObject()->property(index).typeName(); | 704 | if (index != -1) type = metaObject()->property(index).typeName(); |
| 707 | 705 | ||
| 708 | - if ((type.startsWith("QList<") && type.endsWith(">")) || (type == "QStringList")) { | 706 | + if (metaObject()->property(index).isEnumType()) { |
| 707 | + // This is necessary because setProperty can only set enums | ||
| 708 | + // using their integer value if the QVariant is of type int (or uint) | ||
| 709 | + bool ok; | ||
| 710 | + int v = value.toInt(&ok); | ||
| 711 | + if (ok) | ||
| 712 | + value = v; | ||
| 713 | + } else if ((type.startsWith("QList<") && type.endsWith(">")) || (type == "QStringList")) { | ||
| 709 | QVariantList elements; | 714 | QVariantList elements; |
| 710 | if (value.canConvert<QVariantList>()) { | 715 | if (value.canConvert<QVariantList>()) { |
| 711 | elements = value.value<QVariantList>(); | 716 | elements = value.value<QVariantList>(); |
| @@ -766,8 +771,8 @@ void Object::setProperty(const QString &name, QVariant value) | @@ -766,8 +771,8 @@ void Object::setProperty(const QString &name, QVariant value) | ||
| 766 | } | 771 | } |
| 767 | 772 | ||
| 768 | if (!QObject::setProperty(qPrintable(name), value) && !type.isEmpty()) | 773 | if (!QObject::setProperty(qPrintable(name), value) && !type.isEmpty()) |
| 769 | - qFatal("Failed to set %s::%s to: %s", | ||
| 770 | - metaObject()->className(), qPrintable(name), qPrintable(value.toString())); | 774 | + qFatal("Failed to set %s %s::%s to: %s", |
| 775 | + qPrintable(type), metaObject()->className(), qPrintable(name), qPrintable(value.toString())); | ||
| 771 | } | 776 | } |
| 772 | 777 | ||
| 773 | QStringList Object::parse(const QString &string, char split) | 778 | QStringList Object::parse(const QString &string, char split) |
openbr/plugins/meta.cpp
| @@ -717,42 +717,6 @@ public: | @@ -717,42 +717,6 @@ public: | ||
| 717 | }; | 717 | }; |
| 718 | BR_REGISTER(Transform, DistributeTemplateTransform) | 718 | BR_REGISTER(Transform, DistributeTemplateTransform) |
| 719 | 719 | ||
| 720 | -/*! | ||
| 721 | - * \ingroup transforms | ||
| 722 | - * \brief Filters a gallery based on the value of a metadata field. | ||
| 723 | - * \author Brendan Klare \cite bklare | ||
| 724 | - */ | ||
| 725 | -class FilterOnMetadataTransform : public UntrainableMetaTransform | ||
| 726 | -{ | ||
| 727 | - Q_OBJECT | ||
| 728 | - Q_PROPERTY(QString attributeName READ get_attributeName WRITE set_attributeName RESET reset_attributeName STORED false) | ||
| 729 | - Q_PROPERTY(float threshold READ get_threshold WRITE set_threshold RESET reset_threshold STORED false) | ||
| 730 | - Q_PROPERTY(bool isGreaterThan READ get_isGreaterThan WRITE set_isGreaterThan RESET reset_isGreaterThan STORED false) | ||
| 731 | - BR_PROPERTY(QString, attributeName, "Confidence") | ||
| 732 | - BR_PROPERTY(float, threshold, 0) | ||
| 733 | - BR_PROPERTY(bool, isGreaterThan, true) | ||
| 734 | - | ||
| 735 | - void project(const TemplateList &src, TemplateList &dst) const | ||
| 736 | - { | ||
| 737 | - QList<Template> filtered; | ||
| 738 | - foreach (Template t, src) { | ||
| 739 | - if (!t.file.contains(attributeName)) | ||
| 740 | - continue; | ||
| 741 | - bool pass = t.file.get<float>(attributeName) > threshold; | ||
| 742 | - if (isGreaterThan ? pass : !pass) | ||
| 743 | - filtered.append(t); | ||
| 744 | - } | ||
| 745 | - dst = TemplateList(filtered); | ||
| 746 | - } | ||
| 747 | - | ||
| 748 | - void project(const Template &src, Template &dst) const | ||
| 749 | - { | ||
| 750 | - (void) src; (void) dst; qFatal("shouldn't be here"); | ||
| 751 | - } | ||
| 752 | -}; | ||
| 753 | - | ||
| 754 | -BR_REGISTER(Transform, FilterOnMetadataTransform) | ||
| 755 | - | ||
| 756 | } // namespace br | 720 | } // namespace br |
| 757 | 721 | ||
| 758 | #include "meta.moc" | 722 | #include "meta.moc" |
openbr/plugins/openbr_internal.h
| @@ -260,9 +260,19 @@ public: | @@ -260,9 +260,19 @@ public: | ||
| 260 | newTransform = true; | 260 | newTransform = true; |
| 261 | 261 | ||
| 262 | QString name = metaObject()->className(); | 262 | QString name = metaObject()->className(); |
| 263 | + | ||
| 263 | name.replace("Transform",""); | 264 | name.replace("Transform",""); |
| 264 | - name += "([])"; | 265 | + name += "([]"; |
| 266 | + | ||
| 267 | + QStringList arguments = this->arguments(); | ||
| 268 | + if (!arguments.isEmpty()) { | ||
| 269 | + name += ","; | ||
| 270 | + name += this->arguments().join(","); | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + name += ")"; | ||
| 265 | name.replace("br::",""); | 274 | name.replace("br::",""); |
| 275 | + | ||
| 266 | CompositeTransform * output = dynamic_cast<CompositeTransform *>(Transform::make(name, NULL)); | 276 | CompositeTransform * output = dynamic_cast<CompositeTransform *>(Transform::make(name, NULL)); |
| 267 | 277 | ||
| 268 | if (output == NULL) | 278 | if (output == NULL) |
openbr/plugins/regions.cpp
| @@ -372,7 +372,7 @@ class FaceFromEyesTransform : public UntrainableTransform | @@ -372,7 +372,7 @@ class FaceFromEyesTransform : public UntrainableTransform | ||
| 372 | BR_PROPERTY(double, widthPadding, 0.7) | 372 | BR_PROPERTY(double, widthPadding, 0.7) |
| 373 | BR_PROPERTY(double, verticalLocation, 0.25) | 373 | BR_PROPERTY(double, verticalLocation, 0.25) |
| 374 | BR_PROPERTY(int, leftEyeIdx, 0) | 374 | BR_PROPERTY(int, leftEyeIdx, 0) |
| 375 | - BR_PROPERTY(int, rightEyeIdx, 0) | 375 | + BR_PROPERTY(int, rightEyeIdx, 1) |
| 376 | 376 | ||
| 377 | void project(const Template &src, Template &dst) const | 377 | void project(const Template &src, Template &dst) const |
| 378 | { | 378 | { |
| @@ -384,8 +384,8 @@ class FaceFromEyesTransform : public UntrainableTransform | @@ -384,8 +384,8 @@ class FaceFromEyesTransform : public UntrainableTransform | ||
| 384 | return; | 384 | return; |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | - QPointF eyeL = src.file.points()[0]; | ||
| 388 | - QPointF eyeR = src.file.points()[1]; | 387 | + QPointF eyeL = src.file.points()[leftEyeIdx]; |
| 388 | + QPointF eyeR = src.file.points()[rightEyeIdx]; | ||
| 389 | QPointF eyeCenter((eyeL.x() + eyeR.x()) / 2, (eyeL.y() + eyeR.y()) / 2); | 389 | QPointF eyeCenter((eyeL.x() + eyeR.x()) / 2, (eyeL.y() + eyeR.y()) / 2); |
| 390 | float ipd = sqrt(pow(eyeL.x() - eyeR.x(), 2) + pow(eyeL.y() - eyeR.y(), 2)); | 390 | float ipd = sqrt(pow(eyeL.x() - eyeR.x(), 2) + pow(eyeL.y() - eyeR.y(), 2)); |
| 391 | float width = ipd + 2 * widthPadding * ipd; | 391 | float width = ipd + 2 * widthPadding * ipd; |
openbr/plugins/slidingwindow.cpp
| @@ -46,11 +46,13 @@ class SlidingWindowTransform : public MetaTransform | @@ -46,11 +46,13 @@ class SlidingWindowTransform : public MetaTransform | ||
| 46 | Q_PROPERTY(bool takeFirst READ get_takeFirst WRITE set_takeFirst RESET reset_takeFirst STORED false) | 46 | Q_PROPERTY(bool takeFirst READ get_takeFirst WRITE set_takeFirst RESET reset_takeFirst STORED false) |
| 47 | Q_PROPERTY(float threshold READ get_threshold WRITE set_threshold RESET reset_threshold STORED false) | 47 | Q_PROPERTY(float threshold READ get_threshold WRITE set_threshold RESET reset_threshold STORED false) |
| 48 | Q_PROPERTY(float stepFraction READ get_stepFraction WRITE set_stepFraction RESET reset_stepFraction STORED false) | 48 | Q_PROPERTY(float stepFraction READ get_stepFraction WRITE set_stepFraction RESET reset_stepFraction STORED false) |
| 49 | + Q_PROPERTY(int ignoreBorder READ get_ignoreBorder WRITE set_ignoreBorder RESET reset_ignoreBorder STORED false) | ||
| 49 | BR_PROPERTY(br::Transform *, transform, NULL) | 50 | BR_PROPERTY(br::Transform *, transform, NULL) |
| 50 | BR_PROPERTY(int, windowWidth, 24) | 51 | BR_PROPERTY(int, windowWidth, 24) |
| 51 | BR_PROPERTY(bool, takeFirst, false) | 52 | BR_PROPERTY(bool, takeFirst, false) |
| 52 | BR_PROPERTY(float, threshold, 0) | 53 | BR_PROPERTY(float, threshold, 0) |
| 53 | BR_PROPERTY(float, stepFraction, 0.25) | 54 | BR_PROPERTY(float, stepFraction, 0.25) |
| 55 | + BR_PROPERTY(int, ignoreBorder, 0) | ||
| 54 | 56 | ||
| 55 | private: | 57 | private: |
| 56 | int windowHeight; | 58 | int windowHeight; |
| @@ -61,8 +63,17 @@ private: | @@ -61,8 +63,17 @@ private: | ||
| 61 | if (aspectRatio == -1) | 63 | if (aspectRatio == -1) |
| 62 | aspectRatio = getAspectRatio(data); | 64 | aspectRatio = getAspectRatio(data); |
| 63 | windowHeight = qRound(windowWidth / aspectRatio); | 65 | windowHeight = qRound(windowWidth / aspectRatio); |
| 66 | + | ||
| 64 | if (transform->trainable) { | 67 | if (transform->trainable) { |
| 65 | - transform->train(data); | 68 | + TemplateList dataOut = data; |
| 69 | + if (ignoreBorder > 0) { | ||
| 70 | + for (int i = 0; i < dataOut.size(); i++) { | ||
| 71 | + Template t = dataOut[i]; | ||
| 72 | + Mat m = t.m(); | ||
| 73 | + dataOut.replace(i,Template(t.file, Mat(m,Rect(ignoreBorder,ignoreBorder,m.cols - ignoreBorder * 2, m.rows - ignoreBorder * 2)))); | ||
| 74 | + } | ||
| 75 | + } | ||
| 76 | + transform->train(dataOut); | ||
| 66 | } | 77 | } |
| 67 | } | 78 | } |
| 68 | 79 | ||
| @@ -101,7 +112,7 @@ protected: | @@ -101,7 +112,7 @@ protected: | ||
| 101 | foreach (const Template &t, src) { | 112 | foreach (const Template &t, src) { |
| 102 | for (float y = 0; y + windowHeight < t.m().rows; y += windowHeight*stepFraction) { | 113 | for (float y = 0; y + windowHeight < t.m().rows; y += windowHeight*stepFraction) { |
| 103 | for (float x = 0; x + windowWidth < t.m().cols; x += windowWidth*stepFraction) { | 114 | for (float x = 0; x + windowWidth < t.m().cols; x += windowWidth*stepFraction) { |
| 104 | - Mat windowMat(t.m(), Rect(x, y, windowWidth, windowHeight)); | 115 | + Mat windowMat(t.m(), Rect(x + ignoreBorder, y + ignoreBorder, windowWidth - ignoreBorder * 2, windowHeight - ignoreBorder * 2)); |
| 105 | Template detect; | 116 | Template detect; |
| 106 | transform->project(Template(t.file, windowMat), detect); | 117 | transform->project(Template(t.file, windowMat), detect); |
| 107 | 118 |
openbr/plugins/template.cpp
| @@ -50,6 +50,42 @@ class RemoveTemplatesTransform : public UntrainableMetaTransform | @@ -50,6 +50,42 @@ class RemoveTemplatesTransform : public UntrainableMetaTransform | ||
| 50 | 50 | ||
| 51 | BR_REGISTER(Transform, RemoveTemplatesTransform) | 51 | BR_REGISTER(Transform, RemoveTemplatesTransform) |
| 52 | 52 | ||
| 53 | +/*! | ||
| 54 | + * \ingroup transforms | ||
| 55 | + * \brief Filters a gallery based on the value of a metadata field. | ||
| 56 | + * \author Brendan Klare \cite bklare | ||
| 57 | + */ | ||
| 58 | +class FilterOnMetadataTransform : public UntrainableMetaTransform | ||
| 59 | +{ | ||
| 60 | + Q_OBJECT | ||
| 61 | + Q_PROPERTY(QString attributeName READ get_attributeName WRITE set_attributeName RESET reset_attributeName STORED false) | ||
| 62 | + Q_PROPERTY(float threshold READ get_threshold WRITE set_threshold RESET reset_threshold STORED false) | ||
| 63 | + Q_PROPERTY(bool isGreaterThan READ get_isGreaterThan WRITE set_isGreaterThan RESET reset_isGreaterThan STORED false) | ||
| 64 | + BR_PROPERTY(QString, attributeName, "Confidence") | ||
| 65 | + BR_PROPERTY(float, threshold, 0) | ||
| 66 | + BR_PROPERTY(bool, isGreaterThan, true) | ||
| 67 | + | ||
| 68 | + void project(const TemplateList &src, TemplateList &dst) const | ||
| 69 | + { | ||
| 70 | + QList<Template> filtered; | ||
| 71 | + foreach (Template t, src) { | ||
| 72 | + if (!t.file.contains(attributeName)) | ||
| 73 | + continue; | ||
| 74 | + bool pass = t.file.get<float>(attributeName) > threshold; | ||
| 75 | + if (isGreaterThan ? pass : !pass) | ||
| 76 | + filtered.append(t); | ||
| 77 | + } | ||
| 78 | + dst = TemplateList(filtered); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + void project(const Template &src, Template &dst) const | ||
| 82 | + { | ||
| 83 | + (void) src; (void) dst; qFatal("shouldn't be here"); | ||
| 84 | + } | ||
| 85 | +}; | ||
| 86 | + | ||
| 87 | +BR_REGISTER(Transform, FilterOnMetadataTransform) | ||
| 88 | + | ||
| 53 | } // namespace br | 89 | } // namespace br |
| 54 | 90 | ||
| 55 | #include "template.moc" | 91 | #include "template.moc" |