Commit 765897a98c2e3054a06ecfce05645cdf8878aa55

Authored by Josh Klontz
1 parent c290359f

more code

app/openbr-gui/algorithm.cpp 0 → 100644
  1 +#include <QStringList>
  2 +#include <openbr.h>
  3 +
  4 +#include "algorithm.h"
  5 +
  6 +/**** ALGORITHM ****/
  7 +/*** PUBLIC ***/
  8 +br::Algorithm::Algorithm(QWidget *parent)
  9 + : QComboBox(parent)
  10 +{
  11 + setToolTip("Algorithm");
  12 + connect(this, SIGNAL(currentIndexChanged(QString)), this, SLOT(setAlgorithm(QString)));
  13 +}
  14 +
  15 +/*** PUBLIC SLOTS ***/
  16 +bool br::Algorithm::addAlgorithm(const QString &algorithm, const QString &displayName)
  17 +{
  18 + static QStringList availableAlgorithms;
  19 + if (availableAlgorithms.isEmpty())
  20 + availableAlgorithms = QString(br_objects("Abbreviation", ".*", false)).split("\n");
  21 +
  22 + if (!availableAlgorithms.contains(algorithm))
  23 + return false;
  24 +
  25 + if (displayName.isEmpty()) {
  26 + addItem(algorithm);
  27 + } else {
  28 + displayNames.insert(displayName, algorithm);
  29 + addItem(displayName);
  30 + }
  31 + return true;
  32 +}
  33 +
  34 +/*** PRIVATE SLOTS ***/
  35 +void br::Algorithm::setAlgorithm(QString algorithm)
  36 +{
  37 + if (displayNames.contains(algorithm))
  38 + algorithm = displayNames[algorithm];
  39 +
  40 + br_set_property("algorithm", qPrintable(algorithm));
  41 + emit newAlgorithm(algorithm);
  42 +}
  43 +
  44 +#include "moc_algorithm.cpp"
... ...
app/openbr-gui/algorithm.h 0 → 100644
  1 +#ifndef __ALGORITHM_H
  2 +#define __ALGORITHM_H
  3 +
  4 +#include <QComboBox>
  5 +#include <QString>
  6 +#include <QWidget>
  7 +#include <openbr_export.h>
  8 +
  9 +namespace br
  10 +{
  11 +
  12 +class BR_EXPORT_GUI Algorithm : public QComboBox
  13 +{
  14 + Q_OBJECT
  15 + QHash<QString, QString> displayNames;
  16 +
  17 +public:
  18 + explicit Algorithm(QWidget *parent = 0);
  19 +
  20 +public slots:
  21 + bool addAlgorithm(const QString &algorithm, const QString &displayName = "");
  22 +
  23 +private slots:
  24 + void setAlgorithm(QString algorithm);
  25 +
  26 +signals:
  27 + void newAlgorithm(QString algorithm);
  28 +};
  29 +
  30 +}
  31 +
  32 +#endif // __ALGORITHM_H
... ...
app/openbr-gui/classifier.cpp 0 → 100644
  1 +#include <QtConcurrentRun>
  2 +#include <openbr_plugin.h>
  3 +
  4 +#include "classifier.h"
  5 +
  6 +using namespace br;
  7 +
  8 +/**** CLASSIFIER ****/
  9 +/*** PUBLIC ***/
  10 +Classifier::Classifier(QWidget *parent)
  11 + : QLabel(parent)
  12 +{
  13 + setAlignment(Qt::AlignCenter);
  14 + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  15 + connect(this, SIGNAL(newClassification(QString,QString)), this, SLOT(setClassification(QString,QString)));
  16 +}
  17 +
  18 +void Classifier::setAlgorithm(const QString &algorithm)
  19 +{
  20 + this->algorithm = algorithm;
  21 + _classify(File()); // Trigger algorithm initialization
  22 +}
  23 +
  24 +/*** PUBLIC SLOTS ***/
  25 +void Classifier::classify(const File &file)
  26 +{
  27 + QtConcurrent::run(this, &Classifier::_classify, file);
  28 +}
  29 +
  30 +/*** PRIVATE SLOTS ***/
  31 +void Classifier::setClassification(const QString &key, const QString &value)
  32 +{
  33 + if (key.isEmpty()) clear();
  34 + else setText(QString("<b>%1: </b>%2").arg(key, value));
  35 +}
  36 +
  37 +/*** PRIVATE ***/
  38 +void Classifier::_classify(File file)
  39 +{
  40 + file.setBool("forceEnrollment");
  41 +
  42 + QString key, value;
  43 + foreach (const File &f, Enroll(file.flat(), File("[algorithm=" + algorithm + "]"))) {
  44 + qDebug() << f.flat();
  45 + if (!f.contains("Label"))
  46 + continue;
  47 +
  48 + if (algorithm == "GenderClassification") {
  49 + key = "Gender";
  50 + value = (f.getInt("Label", 0) == 0 ? "Male" : "Female");
  51 + } else if (algorithm == "AgeRegression") {
  52 + key = "Age";
  53 + value = QString::number(int(f.getFloat("Label", 0)+0.5)) + " Years";
  54 + } else {
  55 + key = algorithm;
  56 + value = f.getString("Label");
  57 + }
  58 + break;
  59 + }
  60 +
  61 + emit newClassification(key, value);
  62 +}
  63 +
  64 +#include "moc_classifier.cpp"
... ...
app/openbr-gui/classifier.h 0 → 100644
  1 +#ifndef __CLASSIFIER_H
  2 +#define __CLASSIFIER_H
  3 +
  4 +#include <QLabel>
  5 +#include <QWidget>
  6 +#include <QString>
  7 +#include <openbr_plugin.h>
  8 +
  9 +namespace br
  10 +{
  11 +
  12 +class BR_EXPORT_GUI Classifier : public QLabel
  13 +{
  14 + Q_OBJECT
  15 + QString algorithm;
  16 +
  17 +public:
  18 + explicit Classifier(QWidget *parent = 0);
  19 + void setAlgorithm(const QString &algorithm);
  20 +
  21 +public slots:
  22 + void classify(const br::File &file);
  23 +
  24 +private slots:
  25 + void setClassification(const QString &key, const QString &value);
  26 +
  27 +private:
  28 + void _classify(br::File file);
  29 +
  30 +signals:
  31 + void newClassification(QString key, QString value);
  32 +};
  33 +
  34 +} // namespace br
  35 +
  36 +#endif // __CLASSIFIER_H
... ...
app/openbr-gui/dataset.cpp 0 → 100644
  1 +#include <QDir>
  2 +#include <QRegExp>
  3 +#include <QStringList>
  4 +#include <openbr.h>
  5 +
  6 +#include "dataset.h"
  7 +
  8 +/**** DATASET ****/
  9 +/*** PUBLIC ***/
  10 +br::Dataset::Dataset(QWidget *parent)
  11 + : QComboBox(parent)
  12 +{
  13 + setToolTip("Dataset");
  14 + connect(this, SIGNAL(currentIndexChanged(QString)), this, SLOT(datasetChangedTo(QString)));
  15 +}
  16 +
  17 +/*** PUBLIC SLOTS ***/
  18 +static bool compareDatasets(const QString &a, const QString &b)
  19 +{
  20 + static QHash<QString,int> knownDatasets;
  21 + if (knownDatasets.isEmpty()) {
  22 + knownDatasets["MEDS"] = 0;
  23 + knownDatasets["PCSO"] = 1;
  24 + knownDatasets["Good"] = 2;
  25 + knownDatasets["Bad"] = 3;
  26 + knownDatasets["Ugly"] = 4;
  27 + }
  28 +
  29 + if (!knownDatasets.contains(b)) return knownDatasets.contains(a);
  30 + if (!knownDatasets.contains(a)) return false;
  31 + return knownDatasets[a] < knownDatasets[b];
  32 +}
  33 +
  34 +void br::Dataset::setAlgorithm(const QString &algorithm)
  35 +{
  36 + this->algorithm = algorithm;
  37 + QStringList datasets;
  38 + QRegExp re("^" + algorithm + "_(.+).csv$");
  39 + foreach (const QString &file, QDir(QString("%1/share/mm/Algorithm_Dataset/").arg(br_sdk_path())).entryList())
  40 + if (re.indexIn(file) != -1)
  41 + datasets.append(re.cap(1));
  42 + qSort(datasets.begin(), datasets.end(), compareDatasets);
  43 + clear();
  44 + addItems(datasets);
  45 + setVisible(!datasets.isEmpty());
  46 +}
  47 +
  48 +/*** PRIVATE SLOTS ***/
  49 +void br::Dataset::datasetChangedTo(const QString &dataset)
  50 +{
  51 + emit newDataset(dataset);
  52 + emit newDistribution(QString("%1/share/mm/Algorithm_Dataset/%2_%3.csv").arg(br_sdk_path(), algorithm, dataset));
  53 +}
  54 +
  55 +#include "moc_dataset.cpp"
... ...
app/openbr-gui/dataset.h 0 → 100644
  1 +#ifndef __DATASET_H
  2 +#define __DATASET_H
  3 +
  4 +#include <QComboBox>
  5 +#include <QString>
  6 +#include <QWidget>
  7 +#include <openbr_export.h>
  8 +
  9 +namespace br
  10 +{
  11 +
  12 +class BR_EXPORT_GUI Dataset : public QComboBox
  13 +{
  14 + Q_OBJECT
  15 + QString algorithm;
  16 +
  17 +public:
  18 + explicit Dataset(QWidget *parent = 0);
  19 +
  20 +public slots:
  21 + void setAlgorithm(const QString &algorithm);
  22 +
  23 +private slots:
  24 + void datasetChangedTo(const QString &dataset);
  25 +
  26 +signals:
  27 + void newDataset(QString);
  28 + void newDistribution(QString);
  29 +};
  30 +
  31 +} // namespace br
  32 +
  33 +#endif // __DATASET_H
... ...
app/openbr-gui/gallerytoolbar.cpp 0 → 100644
  1 +#include <QDateTime>
  2 +#include <QDesktopServices>
  3 +#include <QDir>
  4 +#include <QFileDialog>
  5 +#include <QIcon>
  6 +#include <QMessageBox>
  7 +#include <QSharedPointer>
  8 +#include <QSize>
  9 +#include <QtConcurrentRun>
  10 +#include <opencv2/highgui/highgui.hpp>
  11 +#include <assert.h>
  12 +#include <openbr_plugin.h>
  13 +
  14 +#include "gallerytoolbar.h"
  15 +#include "utility.h"
  16 +
  17 +/**** GALLERY ****/
  18 +/*** STATIC ***/
  19 +QMutex br::GalleryToolBar::galleryLock;
  20 +
  21 +/*** PUBLIC ***/
  22 +br::GalleryToolBar::GalleryToolBar(QWidget *parent)
  23 + : QToolBar("Gallery", parent)
  24 +{
  25 + lGallery.setAlignment(Qt::AlignCenter);
  26 + lGallery.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  27 + tbOpenFile.setIcon(QIcon(":/glyphicons/png/glyphicons_138_picture@2x.png"));
  28 + tbOpenFile.setToolTip("Load Photo");
  29 + tbOpenFolder.setIcon(QIcon(":/glyphicons/png/glyphicons_144_folder_open@2x.png"));
  30 + tbOpenFolder.setToolTip("Load Photo Folder");
  31 + tbWebcam.setCheckable(true);
  32 + tbWebcam.setIcon(QIcon(":/glyphicons/png/glyphicons_301_webcam@2x.png"));
  33 + tbWebcam.setToolTip("Load Webcam");
  34 + tbBack.setEnabled(false);
  35 + tbBack.setIcon(QIcon(":/glyphicons/png/glyphicons_221_unshare@2x.png"));
  36 + tbBack.setToolTip("Back");
  37 + tbMean.setIcon(QIcon(":/glyphicons/png/glyphicons_003_user@2x.png"));
  38 + tbMean.setToolTip("Mean Image");
  39 +
  40 + addWidget(&tbOpenFile);
  41 + addWidget(&tbOpenFolder);
  42 + addWidget(&tbWebcam);
  43 + addSeparator();
  44 + addWidget(&lGallery);
  45 + addSeparator();
  46 + addWidget(&tbBack);
  47 + addWidget(&tbMean);
  48 + setIconSize(QSize(20,20));
  49 +
  50 + connect(&tbOpenFile, SIGNAL(clicked()), this, SLOT(openFile()));
  51 + connect(&tbOpenFolder, SIGNAL(clicked()), this, SLOT(openFolder()));
  52 + connect(&tbBack, SIGNAL(clicked()), this, SLOT(home()));
  53 + connect(&tbMean, SIGNAL(clicked()), this, SLOT(mean()));
  54 + connect(&enrollmentWatcher, SIGNAL(finished()), this, SLOT(enrollmentFinished()));
  55 + connect(&timer, SIGNAL(timeout()), this, SLOT(checkWebcam()));
  56 +
  57 + timer.start(500);
  58 +}
  59 +
  60 +/*** PUBLIC SLOTS ***/
  61 +void br::GalleryToolBar::enroll(const br::File &input)
  62 +{
  63 + if (input.isNull()) return;
  64 + enrollmentWatcher.setFuture(QtConcurrent::run(this, &GalleryToolBar::_enroll, input));
  65 +}
  66 +
  67 +void br::GalleryToolBar::enroll(const QImage &input)
  68 +{
  69 + QString tempFileName = br::Context::scratchPath() + "/tmp/" + QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss:zzz") + ".png";
  70 + input.save(tempFileName);
  71 + enroll(tempFileName);
  72 +}
  73 +
  74 +void br::GalleryToolBar::select(const br::File &file)
  75 +{
  76 + tbBack.setEnabled(true);
  77 + emit newFiles(br::FileList() << file);
  78 + emit newGallery(file);
  79 +}
  80 +
  81 +/*** PRIVATE ***/
  82 +void br::GalleryToolBar::_enroll(const br::File &input)
  83 +{
  84 + galleryLock.lock();
  85 + this->input = input;
  86 + if (input.suffix() == "gal") gallery = input.name + ".mem";
  87 + else gallery = QString("%1/galleries/%2.gal[cache]").arg(br_scratch_path(), qPrintable(input.baseName()+input.hash()));
  88 + files = br::Enroll(input.flat(), gallery.flat());
  89 + galleryLock.unlock();
  90 +}
  91 +
  92 +void br::GalleryToolBar::_checkWebcam()
  93 +{
  94 + static QSharedPointer<cv::VideoCapture> videoCapture;
  95 + if (videoCapture.isNull()) {
  96 + videoCapture = QSharedPointer<cv::VideoCapture>(new cv::VideoCapture(0));
  97 + cv::Mat m;
  98 + while (!m.data) videoCapture->read(m); // First frames can be empty
  99 + }
  100 +
  101 + if (galleryLock.tryLock()) {
  102 + cv::Mat m;
  103 + videoCapture->read(m);
  104 + galleryLock.unlock();
  105 + enroll(toQImage(m));
  106 + }
  107 +}
  108 +
  109 +/*** PRIVATE SLOTS ***/
  110 +void br::GalleryToolBar::checkWebcam()
  111 +{
  112 + // Check webcam
  113 + if (!tbWebcam.isChecked()) return;
  114 + QtConcurrent::run(this, &GalleryToolBar::_checkWebcam);
  115 +}
  116 +
  117 +void br::GalleryToolBar::enrollmentFinished()
  118 +{
  119 + if (files.isEmpty()) {
  120 + if (!input.getBool("forceEnrollment") && !tbWebcam.isChecked()) {
  121 + QMessageBox msgBox;
  122 + msgBox.setText("Quality test failed.");
  123 + msgBox.setInformativeText("Enroll anyway?");
  124 + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
  125 + msgBox.setDefaultButton(QMessageBox::Ok);
  126 + int ret = msgBox.exec();
  127 +
  128 + if (ret == QMessageBox::Ok) {
  129 + br::File file = input;
  130 + file.setBool("forceEnrollment");
  131 + enroll(file);
  132 + }
  133 + }
  134 + return;
  135 + }
  136 +
  137 + lGallery.setText(input.baseName() + (files.size() != 1 ? " (" + QString::number(files.size()) + ")" : ""));
  138 + tbBack.setEnabled(false);
  139 + emit newFiles(files);
  140 + emit newGallery(gallery);
  141 +}
  142 +
  143 +void br::GalleryToolBar::home()
  144 +{
  145 + tbBack.setEnabled(false);
  146 + emit newGallery(gallery);
  147 +}
  148 +
  149 +void br::GalleryToolBar::mean()
  150 +{
  151 + const QString file = QString("%1/mean/%2.png").arg(br_scratch_path(), input.baseName()+input.hash());
  152 + br_set_property("CENTER_TRAIN_B", qPrintable(file));
  153 + br::File trainingFile = input;
  154 + trainingFile.setBool("forceEnrollment");
  155 + br_train(qPrintable(trainingFile.flat()), "[algorithm=MedianFace]");
  156 + enroll(file);
  157 +}
  158 +
  159 +void br::GalleryToolBar::openFile()
  160 +{
  161 + enroll(QFileDialog::getOpenFileName(this, "Select Photo", QDesktopServices::storageLocation(QDesktopServices::PicturesLocation)));
  162 +}
  163 +
  164 +void br::GalleryToolBar::openFolder()
  165 +{
  166 + enroll(QFileDialog::getExistingDirectory(this, "Select Photo Directory", QDesktopServices::storageLocation(QDesktopServices::HomeLocation)));
  167 +}
  168 +
  169 +#include "moc_gallerytoolbar.cpp"
... ...
app/openbr-gui/gallerytoolbar.h 0 → 100644
  1 +#ifndef __GALLERYTOOLBAR_H
  2 +#define __GALLERYTOOLBAR_H
  3 +
  4 +#include <QFutureWatcher>
  5 +#include <QImage>
  6 +#include <QLabel>
  7 +#include <QMutex>
  8 +#include <QString>
  9 +#include <QTimer>
  10 +#include <QToolBar>
  11 +#include <QToolButton>
  12 +#include <QWidget>
  13 +#include <openbr_plugin.h>
  14 +
  15 +namespace br
  16 +{
  17 +
  18 +class BR_EXPORT_GUI GalleryToolBar : public QToolBar
  19 +{
  20 + Q_OBJECT
  21 + br::File input, gallery;
  22 + br::FileList files;
  23 +
  24 + QLabel lGallery;
  25 + QToolButton tbOpenFile, tbOpenFolder, tbWebcam, tbBack, tbMean;
  26 + QFutureWatcher<void> enrollmentWatcher;
  27 + QTimer timer;
  28 +
  29 + static QMutex galleryLock;
  30 +
  31 +public:
  32 + explicit GalleryToolBar(QWidget *parent = 0);
  33 +
  34 +public slots:
  35 + void enroll(const br::File &input);
  36 + void enroll(const QImage &input);
  37 + void select(const br::File &file);
  38 +
  39 +private:
  40 + void _enroll(const br::File &input);
  41 + void _checkWebcam();
  42 +
  43 +private slots:
  44 + void checkWebcam();
  45 + void enrollmentFinished();
  46 + void home();
  47 + void mean();
  48 + void openFile();
  49 + void openFolder();
  50 +
  51 +signals:
  52 + void newGallery(br::File gallery);
  53 + void newFiles(br::FileList files);
  54 +};
  55 +
  56 +} // namespace br
  57 +
  58 +#endif // GALLERYTOOLBAR_H
... ...
app/openbr-gui/galleryviewer.cpp 0 → 100644
  1 +#include "galleryviewer.h"
  2 +
  3 +using namespace br;
  4 +
  5 +GalleryViewer::GalleryViewer(QWidget *parent)
  6 + : QMainWindow(parent)
  7 +{
  8 + addToolBar(Qt::TopToolBarArea, &gGallery);
  9 + addToolBar(Qt::BottomToolBarArea, &tmTemplateMetadata);
  10 + setCentralWidget(&tvgTemplateViewerGrid);
  11 + setWindowFlags(Qt::Widget);
  12 +
  13 + connect(&tvgTemplateViewerGrid, SIGNAL(newInput(br::File)), &gGallery, SLOT(enroll(br::File)));
  14 + connect(&tvgTemplateViewerGrid, SIGNAL(newInput(QImage)), &gGallery, SLOT(enroll(QImage)));
  15 + connect(&tvgTemplateViewerGrid, SIGNAL(selectedInput(br::File)), &gGallery, SLOT(select(br::File)));
  16 +
  17 + tmTemplateMetadata.addClassifier("GenderClassification", "MM0");
  18 + tmTemplateMetadata.addClassifier("AgeRegression", "MM0");
  19 + setFiles(FileList());
  20 +}
  21 +
  22 +/*** PUBLIC SLOTS ***/
  23 +void GalleryViewer::setAlgorithm(const QString &algorithm)
  24 +{
  25 + tmTemplateMetadata.setAlgorithm(algorithm);
  26 + setFiles(FileList());
  27 +}
  28 +
  29 +void GalleryViewer::setFiles(FileList files)
  30 +{
  31 + bool same = true;
  32 + foreach (const File &file, files) {
  33 + if (file != files.first()) {
  34 + same = false;
  35 + break;
  36 + }
  37 + }
  38 + if (same) files = files.mid(0, 1);
  39 +
  40 + tvgTemplateViewerGrid.setFiles(files);
  41 + tmTemplateMetadata.setVisible(files.size() == 1);
  42 + if (files.size() == 1)
  43 + tmTemplateMetadata.setFile(files.first());
  44 +}
  45 +
  46 +#include "moc_galleryviewer.cpp"
... ...
app/openbr-gui/galleryviewer.h 0 → 100644
  1 +#ifndef GALLERYVIEWER_H
  2 +#define GALLERYVIEWER_H
  3 +
  4 +#include <QMainWindow>
  5 +#include <QWidget>
  6 +#include <openbr_plugin.h>
  7 +
  8 +#include "gallerytoolbar.h"
  9 +#include "templateviewergrid.h"
  10 +#include "templatemetadata.h"
  11 +
  12 +namespace br
  13 +{
  14 +
  15 +class BR_EXPORT_GUI GalleryViewer : public QMainWindow
  16 +{
  17 + Q_OBJECT
  18 +
  19 +public:
  20 + GalleryToolBar gGallery;
  21 + TemplateViewerGrid tvgTemplateViewerGrid;
  22 + TemplateMetadata tmTemplateMetadata;
  23 +
  24 + explicit GalleryViewer(QWidget *parent = 0);
  25 +
  26 +public slots:
  27 + void setAlgorithm(const QString &algorithm);
  28 + void setFiles(br::FileList files);
  29 +};
  30 +
  31 +} // namespace br
  32 +
  33 +#endif // GALLERYVIEWER_H
... ...
app/openbr-gui/help.cpp 0 → 100644
  1 +#include <QDesktopServices>
  2 +#include <QFile>
  3 +#include <QMessageBox>
  4 +#include <QString>
  5 +#include <QUrl>
  6 +#include <openbr.h>
  7 +
  8 +#include "help.h"
  9 +
  10 +/**** HELP ****/
  11 +/*** PUBLIC ***/
  12 +br::Help::Help(QWidget *parent)
  13 + : QMenu(parent)
  14 +{
  15 + actions.append(QSharedPointer<QAction>(addAction("About")));
  16 + connect(actions.last().data(), SIGNAL(triggered()), this, SLOT(showAbout()));
  17 + actions.append(QSharedPointer<QAction>(addAction("Documentation")));
  18 + connect(actions.last().data(), SIGNAL(triggered()), this, SLOT(showDocumentation()));
  19 + actions.append(QSharedPointer<QAction>(addAction("License")));
  20 + connect(actions.last().data(), SIGNAL(triggered()), this, SLOT(showLicense()));
  21 +}
  22 +
  23 +/*** PUBLIC SLOTS ***/
  24 +void br::Help::showAbout()
  25 +{
  26 + QMessageBox::about(this, "About", br_about());
  27 +}
  28 +
  29 +void br::Help::showDocumentation()
  30 +{
  31 + QDesktopServices::openUrl(QUrl(QString("file:///%1/doc/html/index.html").arg(br_sdk_path())));
  32 +}
  33 +
  34 +void br::Help::showLicense()
  35 +{
  36 + QFile file(QString("%1/LICENSE.txt").arg(br_sdk_path()));
  37 + file.open(QFile::ReadOnly);
  38 + QString license = file.readAll();
  39 + file.close();
  40 +
  41 + QMessageBox::about(this, "License", license);
  42 +}
  43 +
  44 +#include "moc_help.cpp"
... ...
app/openbr-gui/help.h 0 → 100644
  1 +#ifndef HELP_H
  2 +#define HELP_H
  3 +
  4 +#include <QAction>
  5 +#include <QList>
  6 +#include <QMenu>
  7 +#include <QSharedPointer>
  8 +#include <QWidget>
  9 +#include <openbr_export.h>
  10 +
  11 +namespace br
  12 +{
  13 +
  14 +class BR_EXPORT_GUI Help : public QMenu
  15 +{
  16 + Q_OBJECT
  17 + QList< QSharedPointer<QAction> > actions;
  18 +
  19 +public:
  20 + explicit Help(QWidget *parent = 0);
  21 +
  22 +public slots:
  23 + void showAbout();
  24 + void showDocumentation();
  25 + void showLicense();
  26 +};
  27 +
  28 +} // namespace br
  29 +
  30 +#endif // HELP_H
... ...
app/openbr-gui/icons.qrc 0 → 100644
  1 +<RCC>
  2 + <qresource prefix="/">
  3 + <file>icons/mitre_logo.png</file>
  4 + <file>icons/mm.png</file>
  5 + </qresource>
  6 +</RCC>
... ...
app/openbr-gui/icons/mitre_logo.png 0 → 100644

57.6 KB

app/openbr-gui/icons/mm.icns 0 → 100644
No preview for this file type
app/openbr-gui/icons/mm.ico 0 → 100644
No preview for this file type
app/openbr-gui/icons/mm.png 0 → 100644

12.2 KB

app/openbr-gui/imageviewer.h
... ... @@ -25,7 +25,6 @@
25 25 #include <QResizeEvent>
26 26 #include <QString>
27 27 #include <QWidget>
28   -
29 28 #include <openbr_export.h>
30 29  
31 30 namespace br
... ...
app/openbr-gui/progress.cpp 0 → 100644
  1 +#include <openbr.h>
  2 +#include <QDebug>
  3 +#include "progress.h"
  4 +
  5 +/**** PROGRESS ****/
  6 +/*** PUBLIC ***/
  7 +br::Progress::Progress(QWidget *parent)
  8 + : QStatusBar(parent)
  9 +{
  10 + pbProgress.setVisible(false);
  11 + pbProgress.setMaximum(100);
  12 + pbProgress.setMinimum(0);
  13 + pbProgress.setValue(0);
  14 + pbProgress.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
  15 + pbProgress.setTextVisible(false);
  16 +
  17 + addWidget(&wSpacer, 1);
  18 + addPermanentWidget(&pbProgress);
  19 + addPermanentWidget(&lTimeRemaining);
  20 + connect(&timer, SIGNAL(timeout()), this, SLOT(checkProgress()));
  21 + timer.start(1000);
  22 +}
  23 +
  24 +/*** PRIVATE SLOTS ***/
  25 +void br::Progress::checkProgress()
  26 +{
  27 + const int progress = 100 * br_progress();
  28 + const bool visible = progress >= 0;
  29 +
  30 + if (visible) {
  31 + showMessage(br_most_recent_message());
  32 + pbProgress.setValue(progress);
  33 + if (progress > 100) pbProgress.setMaximum(0);
  34 + else pbProgress.setMaximum(100);
  35 +
  36 + int s = br_time_remaining();
  37 + if (s >= 0) {
  38 + int h = s / (60*60);
  39 + int m = (s - h*60*60) / 60;
  40 + s = (s - h*60*60 - m*60);
  41 + lTimeRemaining.setText(QString("%1:%2:%3").arg(h, 2, 10, QLatin1Char('0')).arg(m, 2, 10, QLatin1Char('0')).arg(s, 2, 10, QLatin1Char('0')));
  42 + } else {
  43 + lTimeRemaining.clear();
  44 + }
  45 + } else {
  46 + clearMessage();
  47 + lTimeRemaining.clear();
  48 + }
  49 +
  50 + pbProgress.setVisible(visible);
  51 +}
  52 +
  53 +#include "moc_progress.cpp"
... ...
app/openbr-gui/progress.h 0 → 100644
  1 +#ifndef __PROGRESS_H
  2 +#define __PROGRESS_H
  3 +
  4 +#include <QLabel>
  5 +#include <QProgressBar>
  6 +#include <QStatusBar>
  7 +#include <QTimer>
  8 +#include <QWidget>
  9 +#include <openbr_export.h>
  10 +
  11 +namespace br
  12 +{
  13 +
  14 +class BR_EXPORT_GUI Progress : public QStatusBar
  15 +{
  16 + Q_OBJECT
  17 + QWidget wSpacer;
  18 + QProgressBar pbProgress;
  19 + QLabel lTimeRemaining;
  20 + QTimer timer;
  21 +
  22 +public:
  23 + explicit Progress(QWidget *parent = 0);
  24 +
  25 +private slots:
  26 + void checkProgress();
  27 +};
  28 +
  29 +}
  30 +
  31 +#endif // __PROGRESS_H
... ...
app/openbr-gui/score.cpp 0 → 100644
  1 +#include <QDebug>
  2 +#include "score.h"
  3 +
  4 +/**** SCORE ****/
  5 +/*** PUBLIC ***/
  6 +br::Score::Score(QWidget *parent)
  7 + : QLabel(parent)
  8 +{
  9 + setToolTip("Similarity Score");
  10 +}
  11 +
  12 +/*** PUBLIC SLOTS ***/
  13 +void br::Score::setScore(float score)
  14 +{
  15 + setText("<b>Similarity:</b> " + QString::number(score, 'f', 2));
  16 +}
  17 +
  18 +#include "moc_score.cpp"
... ...
app/openbr-gui/score.h 0 → 100644
  1 +#ifndef __SCORE_H
  2 +#define __SCORE_H
  3 +
  4 +#include <QLabel>
  5 +#include <QWidget>
  6 +#include <openbr_export.h>
  7 +
  8 +namespace br
  9 +{
  10 +
  11 +class BR_EXPORT_GUI Score : public QLabel
  12 +{
  13 + Q_OBJECT
  14 +
  15 +public:
  16 + explicit Score(QWidget *parent = 0);
  17 +
  18 +public slots:
  19 + void setScore(float score);
  20 +};
  21 +
  22 +}
  23 +
  24 +#endif // __SCORE_H
... ...
app/openbr-gui/splashscreen.cpp 0 → 100644
  1 +#include <QPixmap>
  2 +#include <openbr_plugin.h>
  3 +
  4 +#include "splashscreen.h"
  5 +
  6 +using namespace br;
  7 +
  8 +/**** SPLASH_SCREEN ****/
  9 +/*** PUBLIC ***/
  10 +SplashScreen::SplashScreen()
  11 + : QSplashScreen(QPixmap(":/icons/mm.png").scaledToWidth(384, Qt::SmoothTransformation))
  12 +{
  13 + connect(&timer, SIGNAL(timeout()), this, SLOT(updateMessage()));
  14 + timer.start(100);
  15 +}
  16 +
  17 +/*** PROTECTED ***/
  18 +void SplashScreen::closeEvent(QCloseEvent *event)
  19 +{
  20 + QSplashScreen::closeEvent(event);
  21 + event->accept();
  22 + timer.stop();
  23 +}
  24 +
  25 +/*** PRIVATE SLOTS ***/
  26 +void SplashScreen::updateMessage()
  27 +{
  28 + showMessage("Version " + Context::version() + " " + QChar(169) + " MITRE 2012\n" + Globals->mostRecentMessage, Qt::AlignHCenter | Qt::AlignBottom);
  29 +}
  30 +
  31 +#include "moc_splashscreen.cpp"
... ...
app/openbr-gui/splashscreen.h 0 → 100644
  1 +#ifndef __SPLASHSCREEN_H
  2 +#define __SPLASHSCREEN_H
  3 +
  4 +#include <QCloseEvent>
  5 +#include <QLabel>
  6 +#include <QSplashScreen>
  7 +#include <QTimer>
  8 +#include <QWidget>
  9 +#include <openbr_export.h>
  10 +
  11 +namespace br
  12 +{
  13 +
  14 +class BR_EXPORT_GUI SplashScreen : public QSplashScreen
  15 +{
  16 + Q_OBJECT
  17 + QTimer timer;
  18 +
  19 +public:
  20 + SplashScreen();
  21 +
  22 +protected:
  23 + void closeEvent(QCloseEvent *event);
  24 +
  25 +private slots:
  26 + void updateMessage();
  27 +};
  28 +
  29 +} // namespace br
  30 +
  31 +#endif // __SPLASHSCREEN_H
... ...
app/openbr-gui/templatemetadata.cpp 0 → 100644
  1 +#include <QAction>
  2 +#include <QFileInfo>
  3 +
  4 +#include "templatemetadata.h"
  5 +
  6 +/*** PUBLIC ***/
  7 +br::TemplateMetadata::TemplateMetadata(QWidget *parent)
  8 + : QToolBar("Template Metadata", parent)
  9 +{
  10 + lFile.setTextInteractionFlags(Qt::TextSelectableByMouse);
  11 + wSpacer.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  12 + addWidget(&wOffset);
  13 + addWidget(&lFile);
  14 + addWidget(&wSpacer);
  15 + addWidget(&lQuality);
  16 +}
  17 +
  18 +void br::TemplateMetadata::addClassifier(const QString &classifier_, const QString algorithm)
  19 +{
  20 + QSharedPointer<Classifier> classifier(new Classifier());
  21 + classifier->setAlgorithm(classifier_);
  22 + QAction *action = addWidget(classifier.data());
  23 + conditionalClassifiers.append(ConditionalClassifier(algorithm, classifier, action));
  24 +}
  25 +
  26 +/**** PRIVATE SLOTS ****/
  27 +void br::TemplateMetadata::setFile(const br::File &file)
  28 +{
  29 + if (file.isNull()) lFile.clear();
  30 + else lFile.setText("<b>File:</b> " + file.fileName());
  31 + lQuality.setText(QString("<b>Quality:</b> %1").arg(file.getBool("FTE") ? "Low" : "High"));
  32 + foreach (const ConditionalClassifier &classifier, conditionalClassifiers)
  33 + if (classifier.action->isVisible()) classifier.classifier->classify(file);
  34 +}
  35 +
  36 +void br::TemplateMetadata::setAlgorithm(const QString &algorithm)
  37 +{
  38 + foreach (const ConditionalClassifier &classifier, conditionalClassifiers) {
  39 + classifier.classifier->clear();
  40 + classifier.action->setVisible(classifier.algorithm.isEmpty() || classifier.algorithm == algorithm);
  41 + }
  42 +}
  43 +
  44 +#include "moc_templatemetadata.cpp"
... ...
app/openbr-gui/templatemetadata.h 0 → 100644
  1 +#ifndef __TEMPLATEMETADATA_H
  2 +#define __TEMPLATEMETADATA_H
  3 +
  4 +#include <QLabel>
  5 +#include <QList>
  6 +#include <QPair>
  7 +#include <QSharedPointer>
  8 +#include <QToolBar>
  9 +#include <QWidget>
  10 +#include <openbr_plugin.h>
  11 +
  12 +#include "classifier.h"
  13 +
  14 +namespace br
  15 +{
  16 +
  17 +class BR_EXPORT_GUI TemplateMetadata : public QToolBar
  18 +{
  19 + Q_OBJECT
  20 + QLabel lFile, lQuality;
  21 + QWidget wOffset, wSpacer;
  22 +
  23 + struct ConditionalClassifier
  24 + {
  25 + QString algorithm;
  26 + QSharedPointer<Classifier> classifier;
  27 + QAction *action;
  28 +
  29 + ConditionalClassifier() : action(NULL) {}
  30 + ConditionalClassifier(const QString &algorithm_, const QSharedPointer<Classifier> &classifier_, QAction *action_)
  31 + : algorithm(algorithm_), classifier(classifier_), action(action_) {}
  32 + };
  33 + QList<ConditionalClassifier> conditionalClassifiers;
  34 +
  35 +public:
  36 + explicit TemplateMetadata(QWidget *parent = 0);
  37 + void addClassifier(const QString &classifier, const QString algorithm = "");
  38 +
  39 +public slots:
  40 + void setFile(const br::File &file);
  41 + void setAlgorithm(const QString &algorithm);
  42 +};
  43 +
  44 +} // namespace br
  45 +
  46 +#endif // TEMPLATEMETADATA_H
... ...
app/openbr-gui/templateviewer.cpp 0 → 100644
  1 +#include <QColor>
  2 +#include <QPainter>
  3 +#include <QPen>
  4 +#include <QUrl>
  5 +#include <QtConcurrentRun>
  6 +#include <openbr.h>
  7 +
  8 +#include "templateviewer.h"
  9 +
  10 +using namespace br;
  11 +
  12 +/*** STATIC ***/
  13 +const int NumLandmarks = 2;
  14 +
  15 +static bool lessThan(const QPointF &a, const QPointF &b)
  16 +{
  17 + return ((a.x() < b.x()) ||
  18 + ((a.x() == b.x()) && (a.y() < b.y())));
  19 +}
  20 +
  21 +/*** PUBLIC ***/
  22 +TemplateViewer::TemplateViewer(QWidget *parent)
  23 + : ImageViewer(parent)
  24 +{
  25 + setAcceptDrops(true);
  26 + setMouseTracking(true);
  27 + setText("<b>Drag Photo or Folder Here</b>\n");
  28 + format = "Registered";
  29 + editable = true;
  30 + setFile(File());
  31 + update();
  32 +}
  33 +
  34 +/*** PUBLIC SLOTS ***/
  35 +void TemplateViewer::setFile(const File &file_)
  36 +{
  37 + this->file = file_;
  38 +
  39 + // Update landmarks
  40 + landmarks.clear();
  41 + if (file.contains("Affine_0_X") && file.contains("Affine_0_Y"))
  42 + landmarks.append(QPointF(file.getFloat("Affine_0_X"), file.getFloat("Affine_0_Y")));
  43 + if (file.contains("Affine_1_X") && file.contains("Affine_1_Y"))
  44 + landmarks.append(QPointF(file.getFloat("Affine_1_X"), file.getFloat("Affine_1_Y")));
  45 + while (landmarks.size() < NumLandmarks)
  46 + landmarks.append(QPointF());
  47 + nearestLandmark = -1;
  48 +
  49 + QtConcurrent::run(this, &TemplateViewer::refreshImage);
  50 +}
  51 +
  52 +void TemplateViewer::setEditable(bool enabled)
  53 +{
  54 + editable = enabled;
  55 + update();
  56 +}
  57 +
  58 +void TemplateViewer::setMousePoint(const QPointF &mousePoint)
  59 +{
  60 + this->mousePoint = mousePoint;
  61 + update();
  62 +}
  63 +
  64 +void TemplateViewer::setFormat(const QString &format)
  65 +{
  66 + this->format = format;
  67 + QtConcurrent::run(this, &TemplateViewer::refreshImage);
  68 +}
  69 +
  70 +/*** PRIVATE ***/
  71 +void TemplateViewer::refreshImage()
  72 +{
  73 + if (file.isNull() || (format == "Photo")) {
  74 + setImage(file, true);
  75 + } else {
  76 + const QString path = QString(br_scratch_path()) + "/thumbnails";
  77 + const QString hash = file.hash()+format;
  78 + const QString processedFile = path+"/"+file.baseName()+hash+".png";
  79 + if (!QFileInfo(processedFile).exists()) {
  80 + if (format == "Registered")
  81 + Enroll(file.flat(), path+"[postfix="+hash+",cache,algorithm=RegisterAffine]");
  82 + else if (format == "Enhanced")
  83 + Enroll(file.flat(), path+"[postfix="+hash+",cache,algorithm=ContrastEnhanced]");
  84 + else if (format == "Features")
  85 + Enroll(file.flat(), path+"[postfix="+hash+",cache,algorithm=ColoredLBP]");
  86 + }
  87 + setImage(processedFile, true);
  88 + }
  89 +}
  90 +
  91 +QPointF TemplateViewer::getImagePoint(const QPointF &sp) const
  92 +{
  93 + if (!pixmap() || isNull()) return QPointF();
  94 + QPointF ip = QPointF(imageWidth()*(sp.x() - (width() - pixmap()->width())/2)/pixmap()->width(),
  95 + imageHeight()*(sp.y() - (height() - pixmap()->height())/2)/pixmap()->height());
  96 + if ((ip.x() < 0) || (ip.x() > imageWidth()) || (ip.y() < 0) || (ip.y() > imageHeight())) return QPointF();
  97 + return ip;
  98 +}
  99 +
  100 +QPointF TemplateViewer::getScreenPoint(const QPointF &ip) const
  101 +{
  102 + if (!pixmap() || isNull()) return QPointF();
  103 + return QPointF(ip.x()*pixmap()->width()/imageWidth() + (width()-pixmap()->width())/2,
  104 + ip.y()*pixmap()->height()/imageHeight() + (height()-pixmap()->height())/2);
  105 +}
  106 +
  107 +/*** PROTECTED SLOTS ***/
  108 +void TemplateViewer::dragEnterEvent(QDragEnterEvent *event)
  109 +{
  110 + ImageViewer::dragEnterEvent(event);
  111 + event->accept();
  112 +
  113 + if (event->mimeData()->hasUrls() || event->mimeData()->hasImage())
  114 + event->acceptProposedAction();
  115 +}
  116 +
  117 +void TemplateViewer::dropEvent(QDropEvent *event)
  118 +{
  119 + ImageViewer::dropEvent(event);
  120 + event->accept();
  121 +
  122 + event->acceptProposedAction();
  123 + const QMimeData *mimeData = event->mimeData();
  124 + if (mimeData->hasImage()) {
  125 + QImage input = qvariant_cast<QImage>(mimeData->imageData());
  126 + emit newInput(input);
  127 + } else if (event->mimeData()->hasUrls()) {
  128 + File input;
  129 + foreach (const QUrl &url, mimeData->urls()) {
  130 + if (!url.isValid()) continue;
  131 + if (url.toString().startsWith("http://images.google.com/search")) continue; // Not a true image URL
  132 + const QString localFile = url.toLocalFile();
  133 + if (localFile.isNull()) input.append(url.toString());
  134 + else input.append(localFile);
  135 + }
  136 + if (input.isNull()) return;
  137 + emit newInput(input);
  138 + }
  139 +}
  140 +
  141 +void TemplateViewer::leaveEvent(QEvent *event)
  142 +{
  143 + ImageViewer::leaveEvent(event);
  144 + event->accept();
  145 + clearFocus();
  146 +
  147 + nearestLandmark = -1;
  148 + mousePoint = QPointF();
  149 + emit newMousePoint(mousePoint);
  150 + unsetCursor();
  151 + update();
  152 +}
  153 +
  154 +void TemplateViewer::mouseMoveEvent(QMouseEvent *event)
  155 +{
  156 + ImageViewer::mouseMoveEvent(event);
  157 + event->accept();
  158 +
  159 + mousePoint = getImagePoint(event->pos());
  160 + nearestLandmark = -1;
  161 + if (!mousePoint.isNull()) {
  162 + double nearestDistance = std::numeric_limits<double>::max();
  163 + for (int i=0; i<NumLandmarks; i++) {
  164 + if (landmarks[i].isNull()) {
  165 + nearestLandmark = -1;
  166 + break;
  167 + }
  168 +
  169 + double dist = sqrt(pow(mousePoint.x() - landmarks[i].x(), 2.0) + pow(mousePoint.y() - landmarks[i].y(), 2.0));
  170 + if (dist < nearestDistance) {
  171 + nearestDistance = dist;
  172 + nearestLandmark = i;
  173 + }
  174 + }
  175 +
  176 + if (format == "Photo") unsetCursor();
  177 + else setCursor(Qt::BlankCursor);
  178 + } else {
  179 + unsetCursor();
  180 + }
  181 +
  182 + emit newMousePoint(mousePoint);
  183 + update();
  184 +}
  185 +
  186 +void TemplateViewer::mousePressEvent(QMouseEvent *event)
  187 +{
  188 + ImageViewer::mousePressEvent(event);
  189 + event->accept();
  190 +
  191 + if (isNull() || getImagePoint(event->pos()).isNull()) return;
  192 +
  193 + if (!editable || (format != "Photo")) {
  194 + emit selectedInput(file);
  195 + return;
  196 + }
  197 +
  198 + int index;
  199 + for (index=0; index<NumLandmarks; index++)
  200 + if (landmarks[index].isNull()) break;
  201 +
  202 + if ((event->button() == Qt::RightButton) || (index == NumLandmarks)) {
  203 + // Remove nearest point
  204 + if (nearestLandmark == -1) return;
  205 + index = nearestLandmark;
  206 + landmarks[nearestLandmark] = QPointF();
  207 + nearestLandmark = -1;
  208 + }
  209 +
  210 + if (event->button() == Qt::LeftButton) {
  211 + // Add a point
  212 + landmarks[index] = getImagePoint(event->pos());
  213 + qSort(landmarks.begin(), landmarks.end(), lessThan);
  214 + if (!landmarks.contains(QPointF()))
  215 + emit selectedInput(file.name+QString("[Affine_0_X=%1, Affine_0_Y=%2, Affine_1_X=%3, Affine_1_Y=%4, forceEnrollment]").arg(QString::number(landmarks[0].x()),
  216 + QString::number(landmarks[0].y()),
  217 + QString::number(landmarks[1].x()),
  218 + QString::number(landmarks[1].y())));
  219 + }
  220 +
  221 + update();
  222 +}
  223 +
  224 +void TemplateViewer::paintEvent(QPaintEvent *event)
  225 +{
  226 + static const QColor nearest(0, 0, 255, 192);
  227 + static const QColor normal(0, 255, 0, 192);
  228 +
  229 + ImageViewer::paintEvent(event);
  230 + event->accept();
  231 +
  232 + QPainter painter(this);
  233 + painter.setRenderHint(QPainter::Antialiasing, true);
  234 +
  235 + if (format == "Photo") {
  236 + for (int i=0; i<NumLandmarks; i++) {
  237 + if (!landmarks[i].isNull()) {
  238 + if ((i == nearestLandmark) &&
  239 + editable) painter.setBrush(QBrush(nearest));
  240 + else painter.setBrush(QBrush(normal));
  241 + painter.drawEllipse(getScreenPoint(landmarks[i]), 4, 4);
  242 + }
  243 + }
  244 + } else {
  245 + if (!mousePoint.isNull() && !isNull()) {
  246 + painter.setPen(QPen(normal));
  247 + painter.drawLine(getScreenPoint(QPointF(mousePoint.x(), 0)), getScreenPoint(QPointF(mousePoint.x(), imageHeight())));
  248 + painter.drawLine(getScreenPoint(QPointF(0, mousePoint.y())), getScreenPoint(QPointF(imageWidth(), mousePoint.y())));
  249 + }
  250 + }
  251 +}
  252 +
  253 +#include "moc_templateviewer.cpp"
... ...
app/openbr-gui/templateviewer.h 0 → 100644
  1 +#ifndef __TEMPLATEVIEWER_H
  2 +#define __TEMPLATEVIEWER_H
  3 +
  4 +#include <QDragEnterEvent>
  5 +#include <QDropEvent>
  6 +#include <QEvent>
  7 +#include <QImage>
  8 +#include <QList>
  9 +#include <QMouseEvent>
  10 +#include <QPointF>
  11 +#include <QString>
  12 +#include <QWidget>
  13 +#include <openbr_plugin.h>
  14 +
  15 +#include "openbr-gui/imageviewer.h"
  16 +
  17 +namespace br
  18 +{
  19 +
  20 +class BR_EXPORT_GUI TemplateViewer : public br::ImageViewer
  21 +{
  22 + Q_OBJECT
  23 + br::File file;
  24 + QPointF mousePoint;
  25 + QString format;
  26 +
  27 + bool editable;
  28 + QList<QPointF> landmarks;
  29 + int nearestLandmark;
  30 +
  31 +public:
  32 + explicit TemplateViewer(QWidget *parent = 0);
  33 +
  34 +public slots:
  35 + void setFile(const br::File &file);
  36 + void setEditable(bool enabled);
  37 + void setMousePoint(const QPointF &mousePoint);
  38 + void setFormat(const QString &format);
  39 +
  40 +private:
  41 + void refreshImage();
  42 + QPointF getImagePoint(const QPointF &sp) const;
  43 + QPointF getScreenPoint(const QPointF &ip) const;
  44 +
  45 +protected slots:
  46 + void dragEnterEvent(QDragEnterEvent *event);
  47 + void dropEvent(QDropEvent *event);
  48 + void leaveEvent(QEvent *event);
  49 + void mouseMoveEvent(QMouseEvent *event);
  50 + void mousePressEvent(QMouseEvent *event);
  51 + void paintEvent(QPaintEvent *event);
  52 +
  53 +signals:
  54 + void newInput(br::File input);
  55 + void newInput(QImage input);
  56 + void newMousePoint(QPointF mousePoint);
  57 + void selectedInput(br::File input);
  58 +};
  59 +
  60 +}
  61 +
  62 +#endif // TEMPLATEVIEWER_H
... ...
app/openbr-gui/templateviewergrid.cpp 0 → 100644
  1 +#include "templateviewergrid.h"
  2 +
  3 +using namespace br;
  4 +
  5 +/**** TEMPLATE_VIEWER_GRID ****/
  6 +/*** PUBLIC ***/
  7 +TemplateViewerGrid::TemplateViewerGrid(QWidget *parent)
  8 + : QWidget(parent)
  9 +{
  10 + setLayout(&gridLayout);
  11 + setFiles(FileList(16));
  12 + setFiles(FileList(1));
  13 +}
  14 +
  15 +/*** PUBLIC SLOTS ***/
  16 +void TemplateViewerGrid::setFiles(const FileList &files)
  17 +{
  18 + const int size = std::max(1, (int)ceil(sqrt((float)files.size())));
  19 + while (templateViewers.size() < size*size) {
  20 + templateViewers.append(QSharedPointer<TemplateViewer>(new TemplateViewer()));
  21 + connect(templateViewers.last().data(), SIGNAL(newInput(br::File)), this, SIGNAL(newInput(br::File)));
  22 + connect(templateViewers.last().data(), SIGNAL(newInput(QImage)), this, SIGNAL(newInput(QImage)));
  23 + connect(templateViewers.last().data(), SIGNAL(newMousePoint(QPointF)), this, SIGNAL(newMousePoint(QPointF)));
  24 + connect(templateViewers.last().data(), SIGNAL(selectedInput(br::File)), this, SIGNAL(selectedInput(br::File)));
  25 + }
  26 +
  27 + { // Clear layout
  28 + QLayoutItem *child;
  29 + while ((child = gridLayout.takeAt(0)) != 0)
  30 + child->widget()->setVisible(false);
  31 + }
  32 +
  33 + for (int i=0; i<templateViewers.size(); i++) {
  34 + if (i < size*size) {
  35 + gridLayout.addWidget(templateViewers[i].data(), i/size, i%size, 1, 1);
  36 + templateViewers[i]->setVisible(true);
  37 + }
  38 +
  39 + if (i < files.size()) {
  40 + templateViewers[i]->setFile(files[i]);
  41 + } else {
  42 + templateViewers[i]->setDefaultText("<b>"+ (size > 1 ? QString() : QString("Drag Photo or Folder Here")) +"</b>");
  43 + templateViewers[i]->setFile(QString());
  44 + }
  45 +
  46 + templateViewers[i]->setEditable(files.size() == 1);
  47 + }
  48 +}
  49 +
  50 +void TemplateViewerGrid::setFormat(const QString &format)
  51 +{
  52 + foreach (const QSharedPointer<TemplateViewer> &templateViewer, templateViewers)
  53 + templateViewer->setFormat(format);
  54 +}
  55 +
  56 +void TemplateViewerGrid::setMousePoint(const QPointF &mousePoint)
  57 +{
  58 + foreach (const QSharedPointer<TemplateViewer> &templateViewer, templateViewers)
  59 + templateViewer->setMousePoint(mousePoint);
  60 +}
  61 +
  62 +#include "moc_templateviewergrid.cpp"
... ...
app/openbr-gui/templateviewergrid.h 0 → 100644
  1 +#ifndef __TEMPLATE_VIEWER_GRID_H
  2 +#define __TEMPLATE_VIEWER_GRID_H
  3 +
  4 +#include <QGridLayout>
  5 +#include <QList>
  6 +#include <QSharedPointer>
  7 +#include <openbr_plugin.h>
  8 +
  9 +#include "templateviewer.h"
  10 +
  11 +namespace br
  12 +{
  13 +
  14 +class BR_EXPORT_GUI TemplateViewerGrid : public QWidget
  15 +{
  16 + Q_OBJECT
  17 +
  18 + QGridLayout gridLayout;
  19 + QList< QSharedPointer<TemplateViewer> > templateViewers;
  20 +
  21 +public:
  22 + explicit TemplateViewerGrid(QWidget *parent = 0);
  23 +
  24 +public slots:
  25 + void setFiles(const br::FileList &file);
  26 + void setFormat(const QString &format);
  27 + void setMousePoint(const QPointF &mousePoint);
  28 +
  29 +signals:
  30 + void newInput(br::File input);
  31 + void newInput(QImage input);
  32 + void newMousePoint(QPointF mousePoint);
  33 + void selectedInput(br::File input);
  34 +};
  35 +
  36 +} // namespace br
  37 +
  38 +#endif // __TEMPLATE_VIEWER_GRID_H
... ...
app/openbr-gui/utility.cpp 0 → 100644
  1 +#include <QImage>
  2 +#include <limits>
  3 +#include <vector>
  4 +#include <opencv2/imgproc/imgproc.hpp>
  5 +
  6 +using namespace cv;
  7 +
  8 +/**** STATIC ****/
  9 +QImage toQImage(const Mat &mat)
  10 +{
  11 + // Convert to 8U depth
  12 + Mat mat8u;
  13 + if (mat.depth() != CV_8U) {
  14 + double globalMin = std::numeric_limits<double>::max();
  15 + double globalMax = -std::numeric_limits<double>::max();
  16 +
  17 + std::vector<Mat> mv;
  18 + split(mat, mv);
  19 + for (size_t i=0; i<mv.size(); i++) {
  20 + double min, max;
  21 + minMaxLoc(mv[i], &min, &max);
  22 + globalMin = std::min(globalMin, min);
  23 + globalMax = std::max(globalMax, max);
  24 + }
  25 + assert(globalMax >= globalMin);
  26 +
  27 + double range = globalMax - globalMin;
  28 + if (range != 0) {
  29 + double scale = 255 / range;
  30 + convertScaleAbs(mat, mat8u, scale, -(globalMin * scale));
  31 + } else {
  32 + // Monochromatic
  33 + mat8u = Mat(mat.size(), CV_8UC1, Scalar((globalMin+globalMax)/2));
  34 + }
  35 + } else {
  36 + mat8u = mat;
  37 + }
  38 +
  39 + // Convert to 3 channels
  40 + Mat mat8uc3;
  41 + if (mat8u.channels() == 4) cvtColor(mat8u, mat8uc3, CV_BGRA2RGB);
  42 + else if (mat8u.channels() == 3) cvtColor(mat8u, mat8uc3, CV_BGR2RGB);
  43 + else if (mat8u.channels() == 1) cvtColor(mat8u, mat8uc3, CV_GRAY2RGB);
  44 +
  45 + return QImage(mat8uc3.data, mat8uc3.cols, mat8uc3.rows, 3*mat8uc3.cols, QImage::Format_RGB888).copy();
  46 +}
... ...
app/openbr-gui/utility.h 0 → 100644
  1 +#ifndef UTILITY_H
  2 +#define UTILITY_H
  3 +
  4 +#include <QImage>
  5 +#include <opencv2/core/core.hpp>
  6 +
  7 +QImage toQImage(const cv::Mat &mat);
  8 +
  9 +#endif // UTILITY_H
... ...
app/openbr-gui/view.cpp 0 → 100644
  1 +#include "view.h"
  2 +
  3 +/**** VIEW ****/
  4 +/*** PUBLIC ***/
  5 +View::View(QWidget *parent)
  6 + : QToolBar(parent)
  7 + , agFormat(parent)
  8 + , agCount(parent)
  9 +{
  10 + agFormat.addAction("Photo");
  11 + agFormat.actions().last()->setShortcut(Qt::ControlModifier + Qt::Key_D);
  12 + agFormat.addAction("Registered");
  13 + agFormat.actions().last()->setShortcut(Qt::ControlModifier + Qt::Key_R);
  14 + agFormat.addAction("Enhanced");
  15 + agFormat.actions().last()->setShortcut(Qt::ControlModifier + Qt::Key_E);
  16 + agFormat.addAction("Features");
  17 + agFormat.actions().last()->setShortcut(Qt::ControlModifier + Qt::Key_F);
  18 +
  19 + agCount.addAction("1");
  20 + agCount.actions().last()->setShortcut(Qt::ControlModifier + Qt::Key_1);
  21 + agCount.addAction("4");
  22 + agCount.actions().last()->setShortcut(Qt::ControlModifier + Qt::Key_2);
  23 + agCount.addAction("9");
  24 + agCount.actions().last()->setShortcut(Qt::ControlModifier + Qt::Key_3);
  25 + agCount.addAction("16");
  26 + agCount.actions().last()->setShortcut(Qt::ControlModifier + Qt::Key_4);
  27 +
  28 + addActions(agFormat.actions());
  29 + addSeparator();
  30 + addActions(agCount.actions());
  31 +
  32 + setToolTip("View");
  33 +
  34 + connect(&agFormat, SIGNAL(triggered(QAction*)), this, SLOT(formatChanged(QAction*)));
  35 + connect(&agCount, SIGNAL(triggered(QAction*)), this, SLOT(countChanged(QAction*)));
  36 +
  37 + foreach (QAction *action, agCount.actions())
  38 + action->setCheckable(true);
  39 + agCount.actions()[2]->setChecked(true);
  40 +
  41 + foreach (QAction *action, agFormat.actions())
  42 + action->setCheckable(true);
  43 + agFormat.actions()[1]->setChecked(true);
  44 +}
  45 +
  46 +/*** PRIVATE SLOTS ***/
  47 +void View::formatChanged(QAction *action)
  48 +{
  49 + emit newFormat(action->text());
  50 +}
  51 +
  52 +void View::countChanged(QAction *action)
  53 +{
  54 + emit newCount(action->text().toInt());
  55 +}
  56 +
  57 +#include "moc_view.cpp"
... ...
app/openbr-gui/view.h 0 → 100644
  1 +#ifndef VIEW_H
  2 +#define VIEW_H
  3 +
  4 +#include <QAction>
  5 +#include <QActionGroup>
  6 +#include <QLabel>
  7 +#include <QString>
  8 +#include <QToolBar>
  9 +#include <QToolButton>
  10 +#include <QWidget>
  11 +
  12 +class View : public QToolBar
  13 +{
  14 + Q_OBJECT
  15 + QToolButton tbPhoto, tbRegistered, tbEnhanced, tbFeatures;
  16 + QToolButton tb1, tb4, tb9, tb16;
  17 + QActionGroup agFormat, agCount;
  18 +
  19 +public:
  20 + explicit View(QWidget *parent = 0);
  21 +
  22 +private slots:
  23 + void formatChanged(QAction *action);
  24 + void countChanged(QAction *action);
  25 +
  26 +signals:
  27 + void newFormat(QString image);
  28 + void newCount(int count);
  29 +};
  30 +
  31 +#endif // VIEW_H
... ...