#include #include #include #include #include #include #include #include "templateviewer.h" using namespace br; /*** STATIC ***/ const int NumLandmarks = 2; static bool lessThan(const QPointF &a, const QPointF &b) { return ((a.x() < b.x()) || ((a.x() == b.x()) && (a.y() < b.y()))); } /*** PUBLIC ***/ TemplateViewer::TemplateViewer(QWidget *parent) : ImageViewer(parent) { setAcceptDrops(true); setMouseTracking(true); setText("Drag Photo or Folder Here\n"); format = "Registered"; editable = true; setFile(File()); update(); } /*** PUBLIC SLOTS ***/ void TemplateViewer::setFile(const File &file_) { this->file = file_; // Update landmarks landmarks.clear(); if (file.contains("Affine_0_X") && file.contains("Affine_0_Y")) landmarks.append(QPointF(file.getFloat("Affine_0_X"), file.getFloat("Affine_0_Y"))); if (file.contains("Affine_1_X") && file.contains("Affine_1_Y")) landmarks.append(QPointF(file.getFloat("Affine_1_X"), file.getFloat("Affine_1_Y"))); while (landmarks.size() < NumLandmarks) landmarks.append(QPointF()); nearestLandmark = -1; QtConcurrent::run(this, &TemplateViewer::refreshImage); } void TemplateViewer::setEditable(bool enabled) { editable = enabled; update(); } void TemplateViewer::setMousePoint(const QPointF &mousePoint) { this->mousePoint = mousePoint; update(); } void TemplateViewer::setFormat(const QString &format) { this->format = format; QtConcurrent::run(this, &TemplateViewer::refreshImage); } /*** PRIVATE ***/ void TemplateViewer::refreshImage() { if (file.isNull() || (format == "Photo")) { setImage(file, true); } else { const QString path = QString(br_scratch_path()) + "/thumbnails"; const QString hash = file.hash()+format; const QString processedFile = path+"/"+file.baseName()+hash+".png"; if (!QFileInfo(processedFile).exists()) { if (format == "Registered") Enroll(file.flat(), path+"[postfix="+hash+",cache,algorithm=RegisterAffine]"); else if (format == "Enhanced") Enroll(file.flat(), path+"[postfix="+hash+",cache,algorithm=ContrastEnhanced]"); else if (format == "Features") Enroll(file.flat(), path+"[postfix="+hash+",cache,algorithm=ColoredLBP]"); } setImage(processedFile, true); } } QPointF TemplateViewer::getImagePoint(const QPointF &sp) const { if (!pixmap() || isNull()) return QPointF(); QPointF ip = QPointF(imageWidth()*(sp.x() - (width() - pixmap()->width())/2)/pixmap()->width(), imageHeight()*(sp.y() - (height() - pixmap()->height())/2)/pixmap()->height()); if ((ip.x() < 0) || (ip.x() > imageWidth()) || (ip.y() < 0) || (ip.y() > imageHeight())) return QPointF(); return ip; } QPointF TemplateViewer::getScreenPoint(const QPointF &ip) const { if (!pixmap() || isNull()) return QPointF(); return QPointF(ip.x()*pixmap()->width()/imageWidth() + (width()-pixmap()->width())/2, ip.y()*pixmap()->height()/imageHeight() + (height()-pixmap()->height())/2); } /*** PROTECTED SLOTS ***/ void TemplateViewer::dragEnterEvent(QDragEnterEvent *event) { ImageViewer::dragEnterEvent(event); event->accept(); if (event->mimeData()->hasUrls() || event->mimeData()->hasImage()) event->acceptProposedAction(); } void TemplateViewer::dropEvent(QDropEvent *event) { ImageViewer::dropEvent(event); event->accept(); event->acceptProposedAction(); const QMimeData *mimeData = event->mimeData(); if (mimeData->hasImage()) { QImage input = qvariant_cast(mimeData->imageData()); emit newInput(input); } else if (event->mimeData()->hasUrls()) { File input; foreach (const QUrl &url, mimeData->urls()) { if (!url.isValid()) continue; if (url.toString().startsWith("http://images.google.com/search")) continue; // Not a true image URL const QString localFile = url.toLocalFile(); if (localFile.isNull()) input.append(url.toString()); else input.append(localFile); } if (input.isNull()) return; emit newInput(input); } } void TemplateViewer::leaveEvent(QEvent *event) { ImageViewer::leaveEvent(event); event->accept(); clearFocus(); nearestLandmark = -1; mousePoint = QPointF(); emit newMousePoint(mousePoint); unsetCursor(); update(); } void TemplateViewer::mouseMoveEvent(QMouseEvent *event) { ImageViewer::mouseMoveEvent(event); event->accept(); mousePoint = getImagePoint(event->pos()); nearestLandmark = -1; if (!mousePoint.isNull()) { double nearestDistance = std::numeric_limits::max(); for (int i=0; iaccept(); if (isNull() || getImagePoint(event->pos()).isNull()) return; if (!editable || (format != "Photo")) { emit selectedInput(file); return; } int index; for (index=0; indexbutton() == Qt::RightButton) || (index == NumLandmarks)) { // Remove nearest point if (nearestLandmark == -1) return; index = nearestLandmark; landmarks[nearestLandmark] = QPointF(); nearestLandmark = -1; } if (event->button() == Qt::LeftButton) { // Add a point landmarks[index] = getImagePoint(event->pos()); qSort(landmarks.begin(), landmarks.end(), lessThan); if (!landmarks.contains(QPointF())) emit selectedInput(file.name+QString("[Affine_0_X=%1, Affine_0_Y=%2, Affine_1_X=%3, Affine_1_Y=%4]").arg(QString::number(landmarks[0].x()), QString::number(landmarks[0].y()), QString::number(landmarks[1].x()), QString::number(landmarks[1].y()))); } update(); } void TemplateViewer::paintEvent(QPaintEvent *event) { static const QColor nearest(0, 0, 255, 192); static const QColor normal(0, 255, 0, 192); ImageViewer::paintEvent(event); event->accept(); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); if (format == "Photo") { for (int i=0; i