Commit 147f9ea11e95c4bc98d70a80d535d5d688b8e775

Authored by Scott Klum
1 parent 6d1a99a0

Added faceviewer

3rdparty/stasm4.0.0/stasm/hatdesc.cpp
@@ -27,7 +27,7 @@ namespace stasm @@ -27,7 +27,7 @@ namespace stasm
27 // (Note: an implementation with cache_g as a vector<vector VEC>> was slower.) 27 // (Note: an implementation with cache_g as a vector<vector VEC>> was slower.)
28 28
29 //static hash_map<unsigned, VEC> cache_g; // cached descriptors 29 //static hash_map<unsigned, VEC> cache_g; // cached descriptors
30 -static const bool TRACE_CACHE = 0; // for checking cache hit rate 30 +//static const bool TRACE_CACHE = 0; // for checking cache hit rate
31 //static int ncalls_g, nhits_g; // only used if TRACE_CACHE 31 //static int ncalls_g, nhits_g; // only used if TRACE_CACHE
32 32
33 static unsigned Key(int x, int y) // pack x,y into 32 bits for cache key 33 static unsigned Key(int x, int y) // pack x,y into 32 bits for cache key
openbr/gui/faceviewer.cpp 0 → 100644
  1 +#include "faceviewer.h"
  2 +
  3 +#include <QPainter>
  4 +#include <QtConcurrentRun>
  5 +
  6 +#include <opencv2/opencv.hpp>
  7 +
  8 +const int NUM_LANDMARKS = 2;
  9 +
  10 +using namespace br;
  11 +using namespace cv;
  12 +
  13 +static QImage toQImage(const Mat &mat)
  14 +{
  15 + // Convert to 8U depth
  16 + Mat mat8u;
  17 + if (mat.depth() != CV_8U) {
  18 + double globalMin = std::numeric_limits<double>::max();
  19 + double globalMax = -std::numeric_limits<double>::max();
  20 +
  21 + std::vector<Mat> mv;
  22 + split(mat, mv);
  23 + for (size_t i=0; i<mv.size(); i++) {
  24 + double min, max;
  25 + minMaxLoc(mv[i], &min, &max);
  26 + globalMin = std::min(globalMin, min);
  27 + globalMax = std::max(globalMax, max);
  28 + }
  29 + assert(globalMax >= globalMin);
  30 +
  31 + double range = globalMax - globalMin;
  32 + if (range != 0) {
  33 + double scale = 255 / range;
  34 + convertScaleAbs(mat, mat8u, scale, -(globalMin * scale));
  35 + } else {
  36 + // Monochromatic
  37 + mat8u = Mat(mat.size(), CV_8UC1, Scalar((globalMin+globalMax)/2));
  38 + }
  39 + } else {
  40 + mat8u = mat;
  41 + }
  42 +
  43 + // Convert to 3 channels
  44 + Mat mat8uc3;
  45 + if (mat8u.channels() == 4) cvtColor(mat8u, mat8uc3, CV_BGRA2RGB);
  46 + else if (mat8u.channels() == 3) cvtColor(mat8u, mat8uc3, CV_BGR2RGB);
  47 + else if (mat8u.channels() == 1) cvtColor(mat8u, mat8uc3, CV_GRAY2RGB);
  48 +
  49 + return QImage(mat8uc3.data, mat8uc3.cols, mat8uc3.rows, 3*mat8uc3.cols, QImage::Format_RGB888).copy();
  50 +}
  51 +
  52 +FaceViewer::FaceViewer(QWidget *parent)
  53 + : TemplateViewer(parent)
  54 +{
  55 + setAcceptDrops(true);
  56 + setFile(File());
  57 + selectionDistance = 4.0;
  58 + editable = false;
  59 + dragging = false;
  60 + update();
  61 +}
  62 +
  63 +// Set file seems fine although refresh image is run concurrently
  64 +
  65 +void FaceViewer::setFile(const File &file_)
  66 +{
  67 + qDebug() << "Setting files...";
  68 +
  69 + this->file = file_;
  70 +
  71 + // Update landmarks
  72 + landmarks.clear();
  73 + if (file.contains("Affine_0")) landmarks.append(file.get<QPointF>("Affine_0"));
  74 + if (file.contains("Affine_1")) landmarks.append(file.get<QPointF>("Affine_1"));
  75 + while (landmarks.size() < NUM_LANDMARKS)
  76 + landmarks.append(QPointF());
  77 + nearestLandmark = -1;
  78 +
  79 + QtConcurrent::run(this, &FaceViewer::refreshImage);
  80 +}
  81 +
  82 +void FaceViewer::refreshImage()
  83 +{
  84 + if (file.isNull()) {
  85 + setImage(file, true);
  86 + } else {
  87 + Transform *t = Transform::make("Open", NULL);
  88 +
  89 + Template dst;
  90 + t->project(file, dst);
  91 +
  92 + QImage image = toQImage(dst.m());
  93 + setImage(image, true);
  94 +
  95 + delete t;
  96 + }
  97 +}
  98 +
  99 +QRect FaceViewer::getImageRect(const QPointF &ip, const QSize &size) const
  100 +{
  101 + if (!pixmap() || isNull()) return QRect();
  102 +
  103 + QRect ir = QRect(ip.x() - size.width()/2.0,
  104 + ip.y() - size.height()/2.0, size.width(), size.height());
  105 +
  106 + if ((ir.x() < 0) || (ir.x() > imageWidth()) || (ir.y() < 0) || (ir.y() > imageHeight())) return QRect();
  107 +
  108 + return ir;
  109 +}
  110 +
  111 +QRectF FaceViewer::getScreenRect(const QPointF &sp, int width_, int height_) const
  112 +{
  113 + if (!pixmap() || isNull()) return QRectF();
  114 +
  115 + QRectF sr = QRectF(sp.x() - width_/2.0, sp.y() - height_/2.0, width_, height_);
  116 +
  117 + return sr;
  118 +}
  119 +
  120 +void FaceViewer::mousePressEvent(QMouseEvent *event)
  121 +{
  122 + ImageViewer::mousePressEvent(event);
  123 + event->accept();
  124 +
  125 + if (isNull()) return;
  126 +
  127 + if (!editable) {
  128 + //emit selectedInput(index);
  129 + return;
  130 + }
  131 +
  132 + if (event->button() == Qt::LeftButton && nearestLandmark != -1) dragging = true;
  133 +
  134 + update();
  135 +}
  136 +
  137 +void FaceViewer::mouseMoveEvent(QMouseEvent *event)
  138 +{
  139 + ImageViewer::mouseMoveEvent(event);
  140 + event->accept();
  141 +
  142 + mousePoint = getImagePoint(event->pos());
  143 +
  144 + if (dragging) {
  145 + landmarks[nearestLandmark] = getImagePoint(event->pos());
  146 + } else {
  147 + nearestLandmark = -1;
  148 + if (!mousePoint.isNull()) {
  149 + double nearestDistance = std::numeric_limits<double>::max();
  150 + for (int i=0; i<NUM_LANDMARKS; i++) {
  151 + if (landmarks[i].isNull()) {
  152 + nearestLandmark = -1;
  153 + break;
  154 + }
  155 +
  156 + double dist = sqrt(pow(mousePoint.x() - landmarks[i].x(), 2.0) + pow(mousePoint.y() - landmarks[i].y(), 2.0));
  157 +
  158 + if (dist < nearestDistance && dist < selectionDistance) {
  159 + nearestDistance = dist;
  160 + nearestLandmark = i;
  161 + }
  162 + }
  163 + } else {
  164 + unsetCursor();
  165 + }
  166 + }
  167 +
  168 + update();
  169 +}
  170 +
  171 +void FaceViewer::mouseReleaseEvent(QMouseEvent *event)
  172 +{
  173 + ImageViewer::mouseReleaseEvent(event);
  174 + event->accept();
  175 +
  176 + if (dragging) {
  177 + dragging = false;
  178 + //emit updateInput(landmarks);
  179 + }
  180 +
  181 + update();
  182 +}
  183 +
  184 +void FaceViewer::paintEvent(QPaintEvent *event)
  185 +{
  186 + static const QColor nearest(0, 255, 0, 192);
  187 + static const QColor normal(255, 0, 0, 192);
  188 +
  189 + ImageViewer::paintEvent(event);
  190 + event->accept();
  191 +
  192 + QPainter painter(this);
  193 + painter.setRenderHint(QPainter::Antialiasing, true);
  194 +
  195 + for (int i=0; i<NUM_LANDMARKS; i++) {
  196 + if (!landmarks[i].isNull() && editable) {
  197 + if (i == nearestLandmark) painter.setBrush(QBrush(nearest));
  198 + else painter.setBrush(QBrush(normal));
  199 + painter.drawEllipse(getScreenPoint(landmarks[i]), 4, 4);
  200 + }
  201 + }
  202 +
  203 + if (!isNull() && dragging && editable) {
  204 + setCursor(QCursor(Qt::BlankCursor));
  205 +
  206 + QSize reticleSize = src.size() *.1;
  207 + QSize displaySize = pixmap()->size() *.3;
  208 +
  209 + QRect reticle = getImageRect(mousePoint, reticleSize);
  210 + QImage reticleImage = src.copy(reticle).scaled(src.size()*2.0, Qt::KeepAspectRatio);
  211 +
  212 + QRectF displayRect = getScreenRect(getScreenPoint(mousePoint), displaySize.width(), displaySize.height());
  213 + painter.drawImage(displayRect, reticleImage);
  214 +
  215 + painter.setPen(QPen(nearest));
  216 + painter.drawLine(getScreenPoint(QPointF(mousePoint.x(), mousePoint.y() - reticleSize.height())), getScreenPoint(QPointF(mousePoint.x(), mousePoint.y() + reticleSize.height())));
  217 + painter.drawLine(getScreenPoint(QPointF(mousePoint.x() - reticleSize.width(), mousePoint.y())), getScreenPoint(QPointF(mousePoint.x() + reticleSize.width(), mousePoint.y())));
  218 + }
  219 + else setCursor(QCursor(Qt::ArrowCursor));
  220 +}
openbr/gui/faceviewer.h 0 → 100644
  1 +#ifndef BR_FACEVIEWER_H
  2 +#define BR_FACEVIEWER_H
  3 +
  4 +#include <openbr/openbr_plugin.h>
  5 +#include <openbr/gui/templateviewer.h>
  6 +
  7 +namespace br
  8 +{
  9 +
  10 +class BR_EXPORT FaceViewer : public TemplateViewer
  11 +{
  12 + Q_OBJECT
  13 +
  14 + int index;
  15 + double selectionDistance;
  16 + bool dragging;
  17 +
  18 +public:
  19 + explicit FaceViewer(QWidget *parent = 0);
  20 + void setFile(const File &file_);
  21 +
  22 +protected slots:
  23 + //void dropEvent(QDropEvent *event);
  24 + void mouseMoveEvent(QMouseEvent *event);
  25 + void mousePressEvent(QMouseEvent *event);
  26 + void mouseReleaseEvent(QMouseEvent *event);
  27 + void paintEvent(QPaintEvent *event);
  28 +
  29 +private:
  30 + void refreshImage();
  31 + QRect getImageRect(const QPointF &ip, const QSize &size) const;
  32 + QRectF getScreenRect(const QPointF &sp, int width_, int height_) const;
  33 +};
  34 +
  35 +}
  36 +
  37 +#endif // BR_FACEVIEWER_H
openbr/gui/templateviewer.h
@@ -19,13 +19,6 @@ namespace br @@ -19,13 +19,6 @@ namespace br
19 class BR_EXPORT TemplateViewer : public ImageViewer 19 class BR_EXPORT TemplateViewer : public ImageViewer
20 { 20 {
21 Q_OBJECT 21 Q_OBJECT
22 - File file;  
23 - QPointF mousePoint;  
24 - QString format;  
25 -  
26 - bool editable;  
27 - QList<QPointF> landmarks;  
28 - int nearestLandmark;  
29 22
30 public: 23 public:
31 explicit TemplateViewer(QWidget *parent = 0); 24 explicit TemplateViewer(QWidget *parent = 0);
@@ -36,11 +29,20 @@ public slots: @@ -36,11 +29,20 @@ public slots:
36 void setMousePoint(const QPointF &mousePoint); 29 void setMousePoint(const QPointF &mousePoint);
37 void setFormat(const QString &format); 30 void setFormat(const QString &format);
38 31
39 -private:  
40 - void refreshImage(); 32 +protected:
  33 + File file;
  34 + QPointF mousePoint;
  35 + QString format;
  36 +
  37 + bool editable;
  38 + QList<QPointF> landmarks;
  39 + int nearestLandmark;
41 QPointF getImagePoint(const QPointF &sp) const; 40 QPointF getImagePoint(const QPointF &sp) const;
42 QPointF getScreenPoint(const QPointF &ip) const; 41 QPointF getScreenPoint(const QPointF &ip) const;
43 42
  43 +private:
  44 + void refreshImage();
  45 +
44 protected slots: 46 protected slots:
45 void dragEnterEvent(QDragEnterEvent *event); 47 void dragEnterEvent(QDragEnterEvent *event);
46 void dropEvent(QDropEvent *event); 48 void dropEvent(QDropEvent *event);