diff --git a/openbr/plugins/draw.cpp b/openbr/plugins/draw.cpp index 3dc6a9b2..6a34de7d 100644 --- a/openbr/plugins/draw.cpp +++ b/openbr/plugins/draw.cpp @@ -44,6 +44,7 @@ class DrawTransform : public UntrainableTransform Q_PROPERTY(int lineThickness READ get_lineThickness WRITE set_lineThickness RESET reset_lineThickness STORED false) Q_PROPERTY(bool named READ get_named WRITE set_named RESET reset_named STORED false) Q_PROPERTY(bool location READ get_location WRITE set_location RESET reset_location STORED false) + Q_PROPERTY(bool eyes READ get_eyes WRITE set_eyes RESET reset_eyes STORED false) BR_PROPERTY(bool, verbose, false) BR_PROPERTY(bool, points, true) BR_PROPERTY(bool, rects, true) @@ -51,6 +52,7 @@ class DrawTransform : public UntrainableTransform BR_PROPERTY(int, lineThickness, 1) BR_PROPERTY(bool, named, true) BR_PROPERTY(bool, location, true) + BR_PROPERTY(bool, eyes, true) void project(const Template &src, Template &dst) const { @@ -71,6 +73,13 @@ class DrawTransform : public UntrainableTransform foreach (const Rect &rect, OpenCVUtils::toRects(src.file.namedRects() + src.file.rects())) rectangle(dst, rect, color, lineThickness); } + if (eyes && src.file.contains("First_Eye") && src.file.contains("Second_Eye")) { + const Point2f &point1 = OpenCVUtils::toPoint(src.file.get("First_Eye")); + const Point2f &point2 = OpenCVUtils::toPoint(src.file.get("Second_Eye")); + const Scalar eyeColor(255, 0, 0); + circle(dst, point1, 3, eyeColor, -1); + circle(dst, point2, 3, eyeColor, -1); + } } }; diff --git a/openbr/plugins/template.cpp b/openbr/plugins/template.cpp index 447a4f8a..2bb5a05e 100644 --- a/openbr/plugins/template.cpp +++ b/openbr/plugins/template.cpp @@ -180,6 +180,50 @@ class SelectPointsTransform : public UntrainableMetadataTransform BR_REGISTER(Transform, SelectPointsTransform) +/*! + * \ingroup transforms + * \brief Averages a set of landmarks into a new landmark + * \author Brendan Klare \cite bklare + */ +class AveragePointsTransform : public UntrainableMetadataTransform +{ + Q_OBJECT + Q_PROPERTY(QList indices READ get_indices WRITE set_indices RESET reset_indices STORED false) + Q_PROPERTY(QString metaName READ get_metaName WRITE set_metaName RESET reset_metaName STORED true) + Q_PROPERTY(bool append READ get_append WRITE set_append RESET reset_append STORED true) + Q_PROPERTY(int nLandmarks READ get_nLandmarks WRITE set_nLandmarks RESET reset_nLandmarks STORED true) + BR_PROPERTY(QList, indices, QList()) + BR_PROPERTY(QString, metaName, "") + BR_PROPERTY(bool, append, false) + BR_PROPERTY(int, nLandmarks, 51) + + void projectMetadata(const File &src, File &dst) const + { + dst = src; + if (src.points().size() != nLandmarks) { + if (Globals->verbose) + qDebug() << "Warning: Face has " << src.points().size() << "points; should be " << nLandmarks; + dst.fte = true; + return; + } + int x1 = 0, + y1 = 0; + + for (int i = 0; i < indices.size(); i++) { + x1 += src.points()[indices[i]].x(); + y1 += src.points()[indices[i]].y(); + } + + QPointF p(x1 / indices.size(), y1 / indices.size()); + if (!metaName.isEmpty()) + dst.set(metaName, p); + if (append) + dst.points().append(p); + } +}; + +BR_REGISTER(Transform, AveragePointsTransform) + /*! * \ingroup transforms * \brief Removes duplicate templates based on a unique metadata key