Commit ffcbc59fe5680bb9a3d65fdeb1d5d66183fc2f3f
1 parent
58c5d8cb
Transform added to convert eye locations to face bounding box
Showing
1 changed file
with
43 additions
and
0 deletions
openbr/plugins/regions.cpp
| @@ -353,6 +353,49 @@ class RectFromPointsTransform : public UntrainableTransform | @@ -353,6 +353,49 @@ class RectFromPointsTransform : public UntrainableTransform | ||
| 353 | 353 | ||
| 354 | BR_REGISTER(Transform, RectFromPointsTransform) | 354 | BR_REGISTER(Transform, RectFromPointsTransform) |
| 355 | 355 | ||
| 356 | +/*! | ||
| 357 | + * \ingroup transforms | ||
| 358 | + * \brief Create face bounding box from two eye locations. `widthPadding` specifies | ||
| 359 | + * what percentage of the interpupliary distance (ipd) will be padded in both | ||
| 360 | + * horizontal directions. The `verticalLocation` specifies where vertically the | ||
| 361 | + * eyes are within the bounding box (0.5 would be the center). | ||
| 362 | + * \author Brendan Klare \cite bklare | ||
| 363 | + */ | ||
| 364 | + | ||
| 365 | +class FaceFromEyesTransform : public UntrainableTransform | ||
| 366 | +{ | ||
| 367 | + Q_OBJECT | ||
| 368 | + Q_PROPERTY(double widthPadding READ get_widthPadding WRITE set_widthPadding RESET reset_widthPadding STORED false) | ||
| 369 | + Q_PROPERTY(double verticalLocation READ get_verticalLocation WRITE set_verticalLocation RESET reset_verticalLocation STORED false) | ||
| 370 | + Q_PROPERTY(int leftEyeIdx READ get_leftEyeIdx WRITE set_leftEyeIdx RESET reset_leftEyeIdx STORED false) | ||
| 371 | + Q_PROPERTY(int rightEyeIdx READ get_rightEyeIdx WRITE set_rightEyeIdx RESET reset_rightEyeIdx STORED false) | ||
| 372 | + BR_PROPERTY(double, widthPadding, 0.7) | ||
| 373 | + BR_PROPERTY(double, verticalLocation, 0.25) | ||
| 374 | + BR_PROPERTY(int, leftEyeIdx, 0) | ||
| 375 | + BR_PROPERTY(int, rightEyeIdx, 0) | ||
| 376 | + | ||
| 377 | + void project(const Template &src, Template &dst) const | ||
| 378 | + { | ||
| 379 | + dst = src; | ||
| 380 | + | ||
| 381 | + if (src.file.points().isEmpty()) { | ||
| 382 | + qWarning("No landmarks"); | ||
| 383 | + dst = src; | ||
| 384 | + return; | ||
| 385 | + } | ||
| 386 | + | ||
| 387 | + QPointF eyeL = src.file.points()[0]; | ||
| 388 | + QPointF eyeR = src.file.points()[1]; | ||
| 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)); | ||
| 391 | + float width = ipd + 2 * widthPadding * ipd; | ||
| 392 | + | ||
| 393 | + dst.file.appendRect(QRectF(eyeCenter.x() - width / 2, eyeCenter.y() - width * verticalLocation, width, width)); | ||
| 394 | + } | ||
| 395 | +}; | ||
| 396 | + | ||
| 397 | +BR_REGISTER(Transform, FaceFromEyesTransform) | ||
| 398 | + | ||
| 356 | } // namespace br | 399 | } // namespace br |
| 357 | 400 | ||
| 358 | #include "regions.moc" | 401 | #include "regions.moc" |