Commit 8058f81d2176b0281b4c2fc4094f6020e5211ded
1 parent
8f957ce1
Added ElicitTransform
Showing
3 changed files
with
185 additions
and
6 deletions
openbr/plugins/gui.cpp
| @@ -5,6 +5,11 @@ | @@ -5,6 +5,11 @@ | ||
| 5 | #include <QMutex> | 5 | #include <QMutex> |
| 6 | #include <QMouseEvent> | 6 | #include <QMouseEvent> |
| 7 | #include <QPainter> | 7 | #include <QPainter> |
| 8 | +#include <QMainWindow> | ||
| 9 | +#include <QPushButton> | ||
| 10 | +#include <QHBoxLayout> | ||
| 11 | +#include <QFormLayout> | ||
| 12 | +#include <QLineEdit> | ||
| 8 | 13 | ||
| 9 | #include <opencv2/imgproc/imgproc.hpp> | 14 | #include <opencv2/imgproc/imgproc.hpp> |
| 10 | #include "openbr_internal.h" | 15 | #include "openbr_internal.h" |
| @@ -188,6 +193,85 @@ private: | @@ -188,6 +193,85 @@ private: | ||
| 188 | 193 | ||
| 189 | }; | 194 | }; |
| 190 | 195 | ||
| 196 | +class DisplayGUI : public QMainWindow | ||
| 197 | +{ | ||
| 198 | + Q_OBJECT | ||
| 199 | + | ||
| 200 | +public: | ||
| 201 | + | ||
| 202 | + DisplayGUI(QWidget * parent = NULL) : QMainWindow(parent) | ||
| 203 | + { | ||
| 204 | + centralWidget = new QWidget(); | ||
| 205 | + layout = new QHBoxLayout(); | ||
| 206 | + inputLayout = new QVBoxLayout(); | ||
| 207 | + | ||
| 208 | + button.setText("Set Template Metadata"); | ||
| 209 | + | ||
| 210 | + layout->addWidget(&label); | ||
| 211 | + | ||
| 212 | + inputLayout->addWidget(&button); | ||
| 213 | + layout->addLayout(inputLayout); | ||
| 214 | + | ||
| 215 | + centralWidget->setLayout(layout); | ||
| 216 | + | ||
| 217 | + setCentralWidget(centralWidget); | ||
| 218 | + | ||
| 219 | + connect(&button, SIGNAL(clicked()), this, SLOT(buttonPressed())); | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | +public slots: | ||
| 223 | + void showImage(const QPixmap & input) | ||
| 224 | + { | ||
| 225 | + pixmap = input; | ||
| 226 | + foreach(const QString& label, keys) { | ||
| 227 | + QLineEdit *edit = new QLineEdit; | ||
| 228 | + fields.append(edit); | ||
| 229 | + QFormLayout *form = new QFormLayout; | ||
| 230 | + form->addRow(label, edit); | ||
| 231 | + inputLayout->addLayout(form); | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + show(); | ||
| 235 | + label.setPixmap(pixmap); | ||
| 236 | + label.setFixedSize(input.size()); | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + QStringList waitForButtonPress() | ||
| 240 | + { | ||
| 241 | + QMutexLocker locker(&lock); | ||
| 242 | + wait.wait(&lock); | ||
| 243 | + | ||
| 244 | + QStringList values; | ||
| 245 | + for(int i = 0; i<fields.size(); i++) values.append(fields.at(i)->text()); | ||
| 246 | + return values; | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | +public slots: | ||
| 250 | + | ||
| 251 | + void buttonPressed() | ||
| 252 | + { | ||
| 253 | + wait.wakeAll(); | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + void setKeys(const QStringList& k) | ||
| 257 | + { | ||
| 258 | + keys = k; | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | +private: | ||
| 262 | + | ||
| 263 | + QWidget *centralWidget; | ||
| 264 | + QStringList keys; | ||
| 265 | + QList<QLineEdit*> fields; | ||
| 266 | + QPushButton button; | ||
| 267 | + QMutex lock; | ||
| 268 | + QWaitCondition wait; | ||
| 269 | + QPixmap pixmap; | ||
| 270 | + QLabel label; | ||
| 271 | + QHBoxLayout *layout; | ||
| 272 | + QVBoxLayout *inputLayout; | ||
| 273 | + | ||
| 274 | +}; | ||
| 191 | 275 | ||
| 192 | // I want a template class that doesn't look like a template class | 276 | // I want a template class that doesn't look like a template class |
| 193 | class NominalCreation | 277 | class NominalCreation |
| @@ -298,7 +382,7 @@ public: | @@ -298,7 +382,7 @@ public: | ||
| 298 | { | 382 | { |
| 299 | dst = src; | 383 | dst = src; |
| 300 | 384 | ||
| 301 | - if (src.empty() || !Globals->useGui) | 385 | + if (src.empty()) |
| 302 | return; | 386 | return; |
| 303 | 387 | ||
| 304 | foreach (const Template & t, src) { | 388 | foreach (const Template & t, src) { |
| @@ -429,6 +513,104 @@ public: | @@ -429,6 +513,104 @@ public: | ||
| 429 | 513 | ||
| 430 | BR_REGISTER(Transform, ManualTransform) | 514 | BR_REGISTER(Transform, ManualTransform) |
| 431 | 515 | ||
| 516 | +/*! | ||
| 517 | + * \ingroup transforms | ||
| 518 | + * \brief Elicits metadata for templates in a pretty GUI | ||
| 519 | + * \author Scott Klum \cite sklum | ||
| 520 | + */ | ||
| 521 | +class ElicitTransform : public TimeVaryingTransform | ||
| 522 | +{ | ||
| 523 | + Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false) | ||
| 524 | + BR_PROPERTY(QStringList, keys, QStringList()) | ||
| 525 | + | ||
| 526 | + Q_OBJECT | ||
| 527 | + | ||
| 528 | + MainThreadCreator creator; | ||
| 529 | + DisplayGUI *gui; | ||
| 530 | + QImage qImageBuffer; | ||
| 531 | + QPixmap *displayBuffer; | ||
| 532 | + | ||
| 533 | +public: | ||
| 534 | + ElicitTransform() : TimeVaryingTransform(false, false) | ||
| 535 | + { | ||
| 536 | + displayBuffer = NULL; | ||
| 537 | + gui = NULL; | ||
| 538 | + } | ||
| 539 | + | ||
| 540 | + ~ElicitTransform() | ||
| 541 | + { | ||
| 542 | + delete displayBuffer; | ||
| 543 | + delete gui; | ||
| 544 | + } | ||
| 545 | + | ||
| 546 | + void train(const TemplateList &data) { (void) data; } | ||
| 547 | + | ||
| 548 | + void project(const TemplateList &src, TemplateList &dst) const | ||
| 549 | + { | ||
| 550 | + Transform * non_const = (ShowTransform *) this; | ||
| 551 | + non_const->projectUpdate(src,dst); | ||
| 552 | + } | ||
| 553 | + | ||
| 554 | + void projectUpdate(const TemplateList &src, TemplateList &dst) | ||
| 555 | + { | ||
| 556 | + dst = src; | ||
| 557 | + | ||
| 558 | + if (src.empty()) return; | ||
| 559 | + | ||
| 560 | + for (int i = 0; i < dst.size(); i++) { | ||
| 561 | + foreach(const cv::Mat &m, dst[i]) { | ||
| 562 | + qImageBuffer = toQImage(m); | ||
| 563 | + displayBuffer->convertFromImage(qImageBuffer); | ||
| 564 | + | ||
| 565 | + emit updateImage(displayBuffer->copy(displayBuffer->rect())); | ||
| 566 | + | ||
| 567 | + QStringList metadata = gui->waitForButtonPress(); | ||
| 568 | + for(int j = 0; j < keys.size(); j++) dst[i].file.set(keys[j],metadata[j]); | ||
| 569 | + } | ||
| 570 | + } | ||
| 571 | + } | ||
| 572 | + | ||
| 573 | + void finalize(TemplateList & output) | ||
| 574 | + { | ||
| 575 | + (void) output; | ||
| 576 | + emit hideWindow(); | ||
| 577 | + } | ||
| 578 | + | ||
| 579 | + void init() | ||
| 580 | + { | ||
| 581 | + initActual<DisplayGUI>(); | ||
| 582 | + } | ||
| 583 | + | ||
| 584 | + template<typename GUIType> | ||
| 585 | + void initActual() | ||
| 586 | + { | ||
| 587 | + if (!Globals->useGui) | ||
| 588 | + return; | ||
| 589 | + | ||
| 590 | + TimeVaryingTransform::init(); | ||
| 591 | + | ||
| 592 | + if (displayBuffer) | ||
| 593 | + delete displayBuffer; | ||
| 594 | + | ||
| 595 | + displayBuffer = new QPixmap(); | ||
| 596 | + | ||
| 597 | + if (gui) | ||
| 598 | + delete gui; | ||
| 599 | + | ||
| 600 | + gui = creator.getItem<GUIType>(); | ||
| 601 | + gui->setKeys(keys); | ||
| 602 | + // Connect our signals to the window's slots | ||
| 603 | + connect(this, SIGNAL(updateImage(QPixmap)), gui,SLOT(showImage(QPixmap))); | ||
| 604 | + connect(this, SIGNAL(hideWindow()), gui, SLOT(hide())); | ||
| 605 | + } | ||
| 606 | + | ||
| 607 | +signals: | ||
| 608 | + | ||
| 609 | + void updateImage(const QPixmap & input); | ||
| 610 | + void hideWindow(); | ||
| 611 | + | ||
| 612 | +}; | ||
| 613 | +BR_REGISTER(Transform, ElicitTransform) | ||
| 432 | 614 | ||
| 433 | /*! | 615 | /*! |
| 434 | * \ingroup transforms | 616 | * \ingroup transforms |
openbr/plugins/misc.cpp
| @@ -332,11 +332,9 @@ class AnonymizeTransform : public UntrainableMetaTransform | @@ -332,11 +332,9 @@ class AnonymizeTransform : public UntrainableMetaTransform | ||
| 332 | 332 | ||
| 333 | BR_REGISTER(Transform, AnonymizeTransform) | 333 | BR_REGISTER(Transform, AnonymizeTransform) |
| 334 | 334 | ||
| 335 | -// TODO: Use a global Mutex to prevent concurrent reads from stdin | ||
| 336 | -#if 0 | ||
| 337 | /*! | 335 | /*! |
| 338 | * \ingroup transforms | 336 | * \ingroup transforms |
| 339 | - * \brief Name a point | 337 | + * \brief Name a metadata value |
| 340 | * \author Scott Klum \cite sklum | 338 | * \author Scott Klum \cite sklum |
| 341 | */ | 339 | */ |
| 342 | class ElicitMetadataTransform : public UntrainableMetaTransform | 340 | class ElicitMetadataTransform : public UntrainableMetaTransform |
| @@ -381,7 +379,6 @@ class ElicitMetadataTransform : public UntrainableMetaTransform | @@ -381,7 +379,6 @@ class ElicitMetadataTransform : public UntrainableMetaTransform | ||
| 381 | }; | 379 | }; |
| 382 | 380 | ||
| 383 | BR_REGISTER(Transform, ElicitMetadataTransform) | 381 | BR_REGISTER(Transform, ElicitMetadataTransform) |
| 384 | -#endif | ||
| 385 | 382 | ||
| 386 | /*! | 383 | /*! |
| 387 | * \ingroup transforms | 384 | * \ingroup transforms |