Commit 4936fcc1c8e0d2bffbe55a4efc4569b0c585416b

Authored by Scott Klum
1 parent e6376e0e

Added ManualTransform for specifying eye locations

3rdparty/stasm4.0.0/stasm/MOD_1/facedet.cpp
... ... @@ -19,6 +19,7 @@ void FaceDet::OpenFaceDetector_( // called by stasm_init, init face det from XML
19 19 const char* datadir, // in: directory of face detector files
20 20 void*) // in: unused (func signature compatibility)
21 21 {
  22 + (void) datadir;
22 23 //OpenDetector(facedet_g, "haarcascade_frontalface_alt2.xml", datadir);
23 24 }
24 25  
... ... @@ -145,6 +146,7 @@ static void TraceFaces( // write image showing detected face rects
145 146 const Image& img, // in
146 147 const char* filename) // in
147 148 {
  149 + (void) detpars, img, filename;
148 150 #if TRACE_IMAGES // will be 0 unless debugging (defined in stasm.h)
149 151  
150 152 CImage cimg; cvtColor(img, cimg, CV_GRAY2BGR); // color image
... ...
3rdparty/stasm4.0.0/stasm/print.cpp
... ... @@ -40,6 +40,7 @@ void OpenLogFile(void) // also inits the global variable logfile_g
40 40  
41 41 void lprintf(const char* format, ...) // args like printf
42 42 {
  43 + (void) format;
43 44 /*
44 45 if (print_g)
45 46 {
... ... @@ -57,6 +58,7 @@ void lprintf(const char* format, ...) // args like printf
57 58  
58 59 void logprintf(const char* format, ...) // args like printf
59 60 {
  61 + (void) format;
60 62 /*
61 63 if (logfile_g)
62 64 {
... ... @@ -76,6 +78,7 @@ void logprintf(const char* format, ...) // args like printf
76 78  
77 79 void lputs(const char* s)
78 80 {
  81 + (void) s;
79 82 /*
80 83 printf("%s", s);
81 84 fflush(stdout); // flush so if there is a crash we can see what happened
... ...
3rdparty/stasm4.0.0/stasm/stasm_lib.cpp
... ... @@ -63,6 +63,8 @@ int stasm_init_ext( // extended version of stasm_init
63 63 int trace, // in: 0 normal use, 1 trace to stdout and stasm.log
64 64 void* detparams) // in: NULL or face detector parameters
65 65 {
  66 + (void) detparams;
  67 +
66 68 int returnval = 1; // assume success
67 69 CatchOpenCvErrs();
68 70 try
... ... @@ -111,6 +113,12 @@ int stasm_open_image_ext( // extended version of stasm_open_image
111 113 int minwidth, // in: min face width as percentage of img width
112 114 void* user) // in: NULL or pointer to user abort func
113 115 {
  116 + (void) img;
  117 + (void) width;
  118 + (void) height;
  119 + (void) imgpath;
  120 + (void) user;
  121 +
114 122 int returnval = 1; // assume success
115 123 CatchOpenCvErrs();
116 124 try
... ... @@ -241,6 +249,11 @@ int stasm_search_pinned( // call after the user has pinned some points
241 249 int height, // in: image height
242 250 const char* imgpath) // in: image path, used only for err msgs and debug
243 251 {
  252 + (void) img;
  253 + (void) width;
  254 + (void) height;
  255 + (void) imgpath;
  256 +
244 257 int returnval = 1; // assume success
245 258 CatchOpenCvErrs();
246 259 try
... ...
openbr/plugins/gui.cpp
... ... @@ -3,6 +3,9 @@
3 3 #include <QElapsedTimer>
4 4 #include <QWaitCondition>
5 5 #include <QMutex>
  6 +#include <QMouseEvent>
  7 +#include <QPainter>
  8 +
6 9 #include <opencv2/imgproc/imgproc.hpp>
7 10 #include "openbr_internal.h"
8 11  
... ... @@ -61,27 +64,31 @@ class GUIProxy : public QObject
61 64  
62 65 public:
63 66  
  67 + QLabel *window;
  68 + QPixmap pixmap;
  69 +
  70 + GUIProxy()
  71 + {
  72 + window = NULL;
  73 + }
  74 +
64 75 bool eventFilter(QObject * obj, QEvent * event)
65 76 {
66 77 if (event->type() == QEvent::KeyPress)
67 78 {
  79 + event->accept();
  80 +
68 81 wait.wakeAll();
  82 + return true;
  83 + } else {
  84 + return QObject::eventFilter(obj, event);
69 85 }
70   - else if (event->type() == QEvent::MouseButtonPress)
71   - {
72   - qDebug() << "hey there";
73   - }
74   - return QObject::eventFilter(obj, event);
75 86 }
76 87  
77   - QLabel * window;
78   - GUIProxy()
  88 + virtual void waitForKey(Template &dst)
79 89 {
80   - window = NULL;
81   - }
  90 + (void) dst;
82 91  
83   - void waitForKey()
84   - {
85 92 QMutexLocker locker(&lock);
86 93 wait.wait(&lock);
87 94 }
... ... @@ -90,8 +97,10 @@ public slots:
90 97  
91 98 void showImage(const QPixmap & input)
92 99 {
  100 + pixmap = input;
  101 +
93 102 window->show();
94   - window->setPixmap(input);
  103 + window->setPixmap(pixmap);
95 104 window->setFixedSize(input.size());
96 105 }
97 106  
... ... @@ -109,6 +118,56 @@ public slots:
109 118 flags = flags & ~Qt::WindowCloseButtonHint;
110 119 window->setWindowFlags(flags);
111 120 }
  121 +
  122 +};
  123 +
  124 +class EyeProxy : public GUIProxy
  125 +{
  126 + Q_OBJECT
  127 +
  128 +public:
  129 +
  130 + bool eventFilter(QObject *obj, QEvent *event)
  131 + {
  132 + if (event->type() == QEvent::MouseButtonPress)
  133 + {
  134 + event->accept();
  135 +
  136 + QMouseEvent *mouseEvent = (QMouseEvent*)event;
  137 +
  138 + if (mouseEvent->button() == Qt::LeftButton) leftEye = mouseEvent->pos();
  139 + else if (mouseEvent->button() == Qt::RightButton) rightEye = mouseEvent->pos();
  140 +
  141 + QPixmap pixmapBuffer = pixmap;
  142 +
  143 + QPainter painter(&pixmapBuffer);
  144 + painter.setBrush(Qt::black);
  145 +
  146 + painter.drawEllipse(leftEye, 4, 4);
  147 + painter.drawEllipse(rightEye, 4, 4);
  148 +
  149 + window->setPixmap(pixmapBuffer);
  150 +
  151 + return true;
  152 + } else {
  153 + return GUIProxy::eventFilter(obj, event);
  154 + }
  155 + }
  156 +
  157 + void waitForKey(Template &dst)
  158 + {
  159 + leftEye = rightEye = QPointF();
  160 +
  161 + GUIProxy::waitForKey(dst);
  162 +
  163 + dst.file.set("leftEye", leftEye);
  164 + dst.file.set("rightEye", rightEye);
  165 + }
  166 +
  167 +private:
  168 +
  169 + QPointF leftEye;
  170 + QPointF rightEye;
112 171 };
113 172  
114 173 /*!
... ... @@ -131,17 +190,6 @@ public:
131 190 {
132 191 gui = NULL;
133 192 displayBuffer = NULL;
134   - if (!Globals->useGui)
135   - return;
136   - displayBuffer = new QPixmap();
137   - // Create our GUI proxy
138   - gui = new GUIProxy();
139   - // Move it to the main thread, this means signals we send to it will
140   - // be run in the main thread, which is hopefully in an event loop
141   - gui->moveToThread(QApplication::instance()->thread());
142   - // Connect our signals to the proxy's slots
143   - connect(this, SIGNAL(needWindow()), gui, SLOT(createWindow()), Qt::BlockingQueuedConnection);
144   - connect(this, SIGNAL(updateImage(QPixmap)), gui,SLOT(showImage(QPixmap)));
145 193 }
146 194  
147 195 ~ShowTransform()
... ... @@ -181,14 +229,16 @@ public:
181 229 qImageBuffer = toQImage(m);
182 230 displayBuffer->convertFromImage(qImageBuffer);
183 231  
184   - // Emit an explicit copy of our pixmap so that the pixmap used
  232 + // Emit an explicit copy of our pixmap so that the pixmap used
185 233 // by the main thread isn't damaged when we update displayBuffer
186 234 // later.
187 235 emit updateImage(displayBuffer->copy(displayBuffer->rect()));
188 236  
189 237 // Blocking wait for a key-press
190   - if (this->waitInput)
191   - gui->waitForKey();
  238 + if (this->waitInput) {
  239 + Template blank;
  240 + gui->waitForKey(blank);
  241 + }
192 242  
193 243 }
194 244 }
... ... @@ -205,6 +255,18 @@ public:
205 255 if (!Globals->useGui)
206 256 return;
207 257  
  258 + displayBuffer = new QPixmap();
  259 +
  260 + // Create our GUI proxy
  261 + gui = new GUIProxy();
  262 + // Move it to the main thread, this means signals we send to it will
  263 + // be run in the main thread, which is hopefully in an event loop
  264 + gui->moveToThread(QApplication::instance()->thread());
  265 +
  266 + // Connect our signals to the proxy's slots
  267 + connect(this, SIGNAL(needWindow()), gui, SLOT(createWindow()), Qt::BlockingQueuedConnection);
  268 + connect(this, SIGNAL(updateImage(QPixmap)), gui,SLOT(showImage(QPixmap)));
  269 +
208 270 emit needWindow();
209 271 connect(this, SIGNAL(changeTitle(QString)), gui->window, SLOT(setWindowTitle(QString)));
210 272 connect(this, SIGNAL(hideWindow()), gui->window, SLOT(hide()));
... ... @@ -221,9 +283,67 @@ signals:
221 283 void changeTitle(const QString & input);
222 284 void hideWindow();
223 285 };
224   -
225 286 BR_REGISTER(Transform, ShowTransform)
226 287  
  288 +/*!
  289 + * \ingroup transforms
  290 + * \brief Displays templates in a GUI pop-up window using QT.
  291 + * \author Charles Otto \cite caotto
  292 + * Can be used with parallelism enabled, although it is considered TimeVarying.
  293 + */
  294 +class ManualTransform : public ShowTransform
  295 +{
  296 + Q_OBJECT
  297 +
  298 + // Specify key
  299 +
  300 +public:
  301 + void projectUpdate(const TemplateList &src, TemplateList &dst)
  302 + {
  303 + dst = src;
  304 +
  305 + if (src.empty() || !Globals->useGui)
  306 + return;
  307 +
  308 + for (int i = 0; i < dst.size(); i++) {
  309 + qImageBuffer = toQImage(dst[i].m());
  310 + displayBuffer->convertFromImage(qImageBuffer);
  311 +
  312 + emit updateImage(displayBuffer->copy(displayBuffer->rect()));
  313 +
  314 + // Blocking wait for a key-press
  315 + if (this->waitInput) {
  316 + gui->waitForKey(dst[i]);
  317 + qDebug() << dst[i].file.get<QPointF>("leftEye");
  318 + qDebug() << dst[i].file.get<QPointF>("rightEye");
  319 + }
  320 + }
  321 + }
  322 +
  323 + void init()
  324 + {
  325 + if (!Globals->useGui)
  326 + return;
  327 +
  328 + displayBuffer = new QPixmap();
  329 +
  330 + // Create our GUI proxy
  331 + gui = new EyeProxy();
  332 +
  333 + // Move it to the main thread, this means signals we send to it will
  334 + // be run in the main thread, which is hopefully in an event loop
  335 + gui->moveToThread(QApplication::instance()->thread());
  336 +
  337 + // Connect our signals to the proxy's slots
  338 + connect(this, SIGNAL(needWindow()), gui, SLOT(createWindow()), Qt::BlockingQueuedConnection);
  339 + connect(this, SIGNAL(updateImage(QPixmap)), gui,SLOT(showImage(QPixmap)));
  340 + emit needWindow();
  341 + connect(this, SIGNAL(hideWindow()), gui->window, SLOT(hide()));
  342 + }
  343 +};
  344 +
  345 +BR_REGISTER(Transform, ManualTransform)
  346 +
227 347 class FPSLimit : public TimeVaryingTransform
228 348 {
229 349 Q_OBJECT
... ...
openbr/plugins/regions.cpp
... ... @@ -15,7 +15,7 @@
15 15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 16  
17 17 #include <opencv2/imgproc/imgproc.hpp>
18   -
  18 +#include "openbr/core/qtutils.h"
19 19 #include "openbr_internal.h"
20 20 #include "openbr/core/opencvutils.h"
21 21  
... ... @@ -239,6 +239,7 @@ BR_REGISTER(Transform, ExpandRectTransform)
239 239 * \ingroup transforms
240 240 * \brief Crops the width and height of a template's rects by input width and height factors.
241 241 * \author Scott Klum \cite sklum
  242 + * \todo Error checking
242 243 */
243 244 class CropRectTransform : public UntrainableTransform
244 245 {
... ... @@ -257,12 +258,12 @@ class CropRectTransform : public UntrainableTransform
257 258 QRectF rect = rects[i];
258 259  
259 260 // Do a bit of error checking
260   - rect.x += rect.width * QtUtils::toPoint(widthCrop).x();
261   - rect.y += rect.height * QtUtils::toPoint(heightCrop).x();
262   - rect.width *= 1-QtUtils::toPoint(widthCrop).y();
263   - rect.height *= 1-QtUtils::toPoint(heightCrop).y();
  261 + rect.setX(rect.x() + rect.width() * QtUtils::toPoint(widthCrop).x());
  262 + rect.setY(rect.y() + rect.height() * QtUtils::toPoint(heightCrop).x());
  263 + rect.setWidth(rect.width() * (1-QtUtils::toPoint(widthCrop).y()));
  264 + rect.setHeight(rect.height() * (1-QtUtils::toPoint(heightCrop).y()));
264 265  
265   - dst.m() = Mat(dst.m(), rect);
  266 + dst.m() = Mat(dst.m(), OpenCVUtils::toRect(rect));
266 267 }
267 268 dst.file.setRects(rects);
268 269 }
... ...