diff --git a/openbr/plugins/gui.cpp b/openbr/plugins/gui.cpp index af2d9fe..96f1c94 100644 --- a/openbr/plugins/gui.cpp +++ b/openbr/plugins/gui.cpp @@ -5,6 +5,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include "openbr_internal.h" @@ -188,6 +193,85 @@ private: }; +class DisplayGUI : public QMainWindow +{ + Q_OBJECT + +public: + + DisplayGUI(QWidget * parent = NULL) : QMainWindow(parent) + { + centralWidget = new QWidget(); + layout = new QHBoxLayout(); + inputLayout = new QVBoxLayout(); + + button.setText("Set Template Metadata"); + + layout->addWidget(&label); + + inputLayout->addWidget(&button); + layout->addLayout(inputLayout); + + centralWidget->setLayout(layout); + + setCentralWidget(centralWidget); + + connect(&button, SIGNAL(clicked()), this, SLOT(buttonPressed())); + } + +public slots: + void showImage(const QPixmap & input) + { + pixmap = input; + foreach(const QString& label, keys) { + QLineEdit *edit = new QLineEdit; + fields.append(edit); + QFormLayout *form = new QFormLayout; + form->addRow(label, edit); + inputLayout->addLayout(form); + } + + show(); + label.setPixmap(pixmap); + label.setFixedSize(input.size()); + } + + QStringList waitForButtonPress() + { + QMutexLocker locker(&lock); + wait.wait(&lock); + + QStringList values; + for(int i = 0; itext()); + return values; + } + +public slots: + + void buttonPressed() + { + wait.wakeAll(); + } + + void setKeys(const QStringList& k) + { + keys = k; + } + +private: + + QWidget *centralWidget; + QStringList keys; + QList fields; + QPushButton button; + QMutex lock; + QWaitCondition wait; + QPixmap pixmap; + QLabel label; + QHBoxLayout *layout; + QVBoxLayout *inputLayout; + +}; // I want a template class that doesn't look like a template class class NominalCreation @@ -298,7 +382,7 @@ public: { dst = src; - if (src.empty() || !Globals->useGui) + if (src.empty()) return; foreach (const Template & t, src) { @@ -429,6 +513,104 @@ public: BR_REGISTER(Transform, ManualTransform) +/*! + * \ingroup transforms + * \brief Elicits metadata for templates in a pretty GUI + * \author Scott Klum \cite sklum + */ +class ElicitTransform : public TimeVaryingTransform +{ + Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false) + BR_PROPERTY(QStringList, keys, QStringList()) + + Q_OBJECT + + MainThreadCreator creator; + DisplayGUI *gui; + QImage qImageBuffer; + QPixmap *displayBuffer; + +public: + ElicitTransform() : TimeVaryingTransform(false, false) + { + displayBuffer = NULL; + gui = NULL; + } + + ~ElicitTransform() + { + delete displayBuffer; + delete gui; + } + + void train(const TemplateList &data) { (void) data; } + + void project(const TemplateList &src, TemplateList &dst) const + { + Transform * non_const = (ShowTransform *) this; + non_const->projectUpdate(src,dst); + } + + void projectUpdate(const TemplateList &src, TemplateList &dst) + { + dst = src; + + if (src.empty()) return; + + for (int i = 0; i < dst.size(); i++) { + foreach(const cv::Mat &m, dst[i]) { + qImageBuffer = toQImage(m); + displayBuffer->convertFromImage(qImageBuffer); + + emit updateImage(displayBuffer->copy(displayBuffer->rect())); + + QStringList metadata = gui->waitForButtonPress(); + for(int j = 0; j < keys.size(); j++) dst[i].file.set(keys[j],metadata[j]); + } + } + } + + void finalize(TemplateList & output) + { + (void) output; + emit hideWindow(); + } + + void init() + { + initActual(); + } + + template + void initActual() + { + if (!Globals->useGui) + return; + + TimeVaryingTransform::init(); + + if (displayBuffer) + delete displayBuffer; + + displayBuffer = new QPixmap(); + + if (gui) + delete gui; + + gui = creator.getItem(); + gui->setKeys(keys); + // Connect our signals to the window's slots + connect(this, SIGNAL(updateImage(QPixmap)), gui,SLOT(showImage(QPixmap))); + connect(this, SIGNAL(hideWindow()), gui, SLOT(hide())); + } + +signals: + + void updateImage(const QPixmap & input); + void hideWindow(); + +}; +BR_REGISTER(Transform, ElicitTransform) /*! * \ingroup transforms diff --git a/openbr/plugins/misc.cpp b/openbr/plugins/misc.cpp index a799968..b8955e2 100644 --- a/openbr/plugins/misc.cpp +++ b/openbr/plugins/misc.cpp @@ -332,11 +332,9 @@ class AnonymizeTransform : public UntrainableMetaTransform BR_REGISTER(Transform, AnonymizeTransform) -// TODO: Use a global Mutex to prevent concurrent reads from stdin -#if 0 /*! * \ingroup transforms - * \brief Name a point + * \brief Name a metadata value * \author Scott Klum \cite sklum */ class ElicitMetadataTransform : public UntrainableMetaTransform @@ -381,7 +379,6 @@ class ElicitMetadataTransform : public UntrainableMetaTransform }; BR_REGISTER(Transform, ElicitMetadataTransform) -#endif /*! * \ingroup transforms diff --git a/share/openbr/models b/share/openbr/models index a73d510..dccddf4 160000 --- a/share/openbr/models +++ b/share/openbr/models @@ -1 +1 @@ -Subproject commit a73d51013ea05f263e88a28539393159fff2183e +Subproject commit dccddf4dd3a5239911807beeec39308f8890b1e4