diff --git a/3rdparty/stasm4.0.0/stasm/hatdesc.cpp b/3rdparty/stasm4.0.0/stasm/hatdesc.cpp index 479b1c7..1f8e020 100755 --- a/3rdparty/stasm4.0.0/stasm/hatdesc.cpp +++ b/3rdparty/stasm4.0.0/stasm/hatdesc.cpp @@ -27,7 +27,7 @@ namespace stasm // (Note: an implementation with cache_g as a vector> was slower.) //static hash_map cache_g; // cached descriptors -static const bool TRACE_CACHE = 0; // for checking cache hit rate +//static const bool TRACE_CACHE = 0; // for checking cache hit rate //static int ncalls_g, nhits_g; // only used if TRACE_CACHE static unsigned Key(int x, int y) // pack x,y into 32 bits for cache key diff --git a/openbr/gui/faceviewer.cpp b/openbr/gui/faceviewer.cpp new file mode 100644 index 0000000..d9f8668 --- /dev/null +++ b/openbr/gui/faceviewer.cpp @@ -0,0 +1,220 @@ +#include "faceviewer.h" + +#include +#include + +#include + +const int NUM_LANDMARKS = 2; + +using namespace br; +using namespace cv; + +static QImage toQImage(const Mat &mat) +{ + // Convert to 8U depth + Mat mat8u; + if (mat.depth() != CV_8U) { + double globalMin = std::numeric_limits::max(); + double globalMax = -std::numeric_limits::max(); + + std::vector mv; + split(mat, mv); + for (size_t i=0; i= globalMin); + + double range = globalMax - globalMin; + if (range != 0) { + double scale = 255 / range; + convertScaleAbs(mat, mat8u, scale, -(globalMin * scale)); + } else { + // Monochromatic + mat8u = Mat(mat.size(), CV_8UC1, Scalar((globalMin+globalMax)/2)); + } + } else { + mat8u = mat; + } + + // Convert to 3 channels + Mat mat8uc3; + if (mat8u.channels() == 4) cvtColor(mat8u, mat8uc3, CV_BGRA2RGB); + else if (mat8u.channels() == 3) cvtColor(mat8u, mat8uc3, CV_BGR2RGB); + else if (mat8u.channels() == 1) cvtColor(mat8u, mat8uc3, CV_GRAY2RGB); + + return QImage(mat8uc3.data, mat8uc3.cols, mat8uc3.rows, 3*mat8uc3.cols, QImage::Format_RGB888).copy(); +} + +FaceViewer::FaceViewer(QWidget *parent) + : TemplateViewer(parent) +{ + setAcceptDrops(true); + setFile(File()); + selectionDistance = 4.0; + editable = false; + dragging = false; + update(); +} + +// Set file seems fine although refresh image is run concurrently + +void FaceViewer::setFile(const File &file_) +{ + qDebug() << "Setting files..."; + + this->file = file_; + + // Update landmarks + landmarks.clear(); + if (file.contains("Affine_0")) landmarks.append(file.get("Affine_0")); + if (file.contains("Affine_1")) landmarks.append(file.get("Affine_1")); + while (landmarks.size() < NUM_LANDMARKS) + landmarks.append(QPointF()); + nearestLandmark = -1; + + QtConcurrent::run(this, &FaceViewer::refreshImage); +} + +void FaceViewer::refreshImage() +{ + if (file.isNull()) { + setImage(file, true); + } else { + Transform *t = Transform::make("Open", NULL); + + Template dst; + t->project(file, dst); + + QImage image = toQImage(dst.m()); + setImage(image, true); + + delete t; + } +} + +QRect FaceViewer::getImageRect(const QPointF &ip, const QSize &size) const +{ + if (!pixmap() || isNull()) return QRect(); + + QRect ir = QRect(ip.x() - size.width()/2.0, + ip.y() - size.height()/2.0, size.width(), size.height()); + + if ((ir.x() < 0) || (ir.x() > imageWidth()) || (ir.y() < 0) || (ir.y() > imageHeight())) return QRect(); + + return ir; +} + +QRectF FaceViewer::getScreenRect(const QPointF &sp, int width_, int height_) const +{ + if (!pixmap() || isNull()) return QRectF(); + + QRectF sr = QRectF(sp.x() - width_/2.0, sp.y() - height_/2.0, width_, height_); + + return sr; +} + +void FaceViewer::mousePressEvent(QMouseEvent *event) +{ + ImageViewer::mousePressEvent(event); + event->accept(); + + if (isNull()) return; + + if (!editable) { + //emit selectedInput(index); + return; + } + + if (event->button() == Qt::LeftButton && nearestLandmark != -1) dragging = true; + + update(); +} + +void FaceViewer::mouseMoveEvent(QMouseEvent *event) +{ + ImageViewer::mouseMoveEvent(event); + event->accept(); + + mousePoint = getImagePoint(event->pos()); + + if (dragging) { + landmarks[nearestLandmark] = getImagePoint(event->pos()); + } else { + nearestLandmark = -1; + if (!mousePoint.isNull()) { + double nearestDistance = std::numeric_limits::max(); + for (int i=0; iaccept(); + + if (dragging) { + dragging = false; + //emit updateInput(landmarks); + } + + update(); +} + +void FaceViewer::paintEvent(QPaintEvent *event) +{ + static const QColor nearest(0, 255, 0, 192); + static const QColor normal(255, 0, 0, 192); + + ImageViewer::paintEvent(event); + event->accept(); + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, true); + + for (int i=0; isize() *.3; + + QRect reticle = getImageRect(mousePoint, reticleSize); + QImage reticleImage = src.copy(reticle).scaled(src.size()*2.0, Qt::KeepAspectRatio); + + QRectF displayRect = getScreenRect(getScreenPoint(mousePoint), displaySize.width(), displaySize.height()); + painter.drawImage(displayRect, reticleImage); + + painter.setPen(QPen(nearest)); + painter.drawLine(getScreenPoint(QPointF(mousePoint.x(), mousePoint.y() - reticleSize.height())), getScreenPoint(QPointF(mousePoint.x(), mousePoint.y() + reticleSize.height()))); + painter.drawLine(getScreenPoint(QPointF(mousePoint.x() - reticleSize.width(), mousePoint.y())), getScreenPoint(QPointF(mousePoint.x() + reticleSize.width(), mousePoint.y()))); + } + else setCursor(QCursor(Qt::ArrowCursor)); +} diff --git a/openbr/gui/faceviewer.h b/openbr/gui/faceviewer.h new file mode 100644 index 0000000..5820639 --- /dev/null +++ b/openbr/gui/faceviewer.h @@ -0,0 +1,37 @@ +#ifndef BR_FACEVIEWER_H +#define BR_FACEVIEWER_H + +#include +#include + +namespace br +{ + +class BR_EXPORT FaceViewer : public TemplateViewer +{ + Q_OBJECT + + int index; + double selectionDistance; + bool dragging; + +public: + explicit FaceViewer(QWidget *parent = 0); + void setFile(const File &file_); + +protected slots: + //void dropEvent(QDropEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); + +private: + void refreshImage(); + QRect getImageRect(const QPointF &ip, const QSize &size) const; + QRectF getScreenRect(const QPointF &sp, int width_, int height_) const; +}; + +} + +#endif // BR_FACEVIEWER_H diff --git a/openbr/gui/templateviewer.h b/openbr/gui/templateviewer.h index 932ac64..40a8bf1 100644 --- a/openbr/gui/templateviewer.h +++ b/openbr/gui/templateviewer.h @@ -19,13 +19,6 @@ namespace br class BR_EXPORT TemplateViewer : public ImageViewer { Q_OBJECT - File file; - QPointF mousePoint; - QString format; - - bool editable; - QList landmarks; - int nearestLandmark; public: explicit TemplateViewer(QWidget *parent = 0); @@ -36,11 +29,20 @@ public slots: void setMousePoint(const QPointF &mousePoint); void setFormat(const QString &format); -private: - void refreshImage(); +protected: + File file; + QPointF mousePoint; + QString format; + + bool editable; + QList landmarks; + int nearestLandmark; QPointF getImagePoint(const QPointF &sp) const; QPointF getScreenPoint(const QPointF &ip) const; +private: + void refreshImage(); + protected slots: void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event);