Fawkes API Fawkes Development Version
qa_facesclassifier.cpp
1
2/***************************************************************************
3 * qa_camargp.h - QA for camera argument parser
4 *
5 * Generated: Wed Apr 11 16:02:33 2007
6 * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
7 * 2009 Daniel Beck
8 *
9 ****************************************************************************/
10
11/* This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. A runtime exception applies to
15 * this software (see LICENSE.GPL_WRE file mentioned below for details).
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
23 */
24
25/// @cond QA
26
27#include <cams/factory.h>
28#include <classifiers/faces.h>
29#include <filters/roidraw.h>
30#include <fvutils/adapters/cvmatadapter.h>
31#include <fvutils/color/colorspaces.h>
32#include <fvutils/draw/drawer.h>
33#include <fvutils/readers/jpeg.h>
34#include <fvwidgets/image_display.h>
35#include <utils/system/argparser.h>
36#include <utils/time/tracker.h>
37
38#include <SDL.h>
39#include <cstdio>
40#include <cstdlib>
41#include <opencv2/opencv.hpp>
42
43using namespace fawkes;
44
45int
46main(int argc, char **argv)
47{
48 ArgumentParser *argp = new ArgumentParser(argc, argv, "h:f:c:");
49
50 if (argp->has_arg("h") && argp->has_arg("f"))
51 // read image from file
52 {
53 const char *cascade_file = argp->arg("h");
54 const char *image_file = argp->arg("f");
55
56 JpegReader * reader = new JpegReader(image_file);
57 unsigned char *buffer =
58 malloc_buffer(YUV422_PLANAR, reader->pixel_width(), reader->pixel_height());
59
60 reader->set_buffer(buffer);
61 reader->read();
62
63 FacesClassifier *classifier =
64 new FacesClassifier(cascade_file, reader->pixel_width(), reader->pixel_height());
65
66 classifier->set_src_buffer(buffer, reader->pixel_width(), reader->pixel_height());
67 std::list<ROI> *rois = classifier->classify();
68
69 FilterROIDraw *roi_draw = new FilterROIDraw();
70 for (std::list<ROI>::iterator i = rois->begin(); i != rois->end(); ++i) {
71 printf("ROI: start (%u, %u) extent %u x %u\n",
72 (*i).start.x,
73 (*i).start.y,
74 (*i).width,
75 (*i).height);
76
77 roi_draw->set_dst_buffer(buffer, &(*i));
78 roi_draw->apply();
79 }
80
81 ImageDisplay *display = new ImageDisplay(reader->pixel_width(), reader->pixel_height());
82 display->show(buffer);
83
84 display->loop_until_quit();
85
86 delete display;
87
88 delete rois;
89 free(buffer);
90 delete reader;
91 delete classifier;
92 }
93
94 else if (argp->has_arg("h") && argp->has_arg("c"))
95 // get images from camera
96 {
97 const char *cascade_file = argp->arg("h");
98
99 Camera *camera = NULL;
100 try {
101 camera = CameraFactory::instance(argp->arg("c"));
102 camera->open();
103 camera->start();
104 } catch (Exception &e) {
105 printf("Failed to open camera.\n");
106 delete camera;
107 return (-1);
108 }
109
110 printf("successfully opened camera: w=%d h=%d\n",
111 camera->pixel_width(),
112 camera->pixel_height());
113
114 TimeTracker *tt = new TimeTracker();
115 unsigned int ttc_recognition = tt->add_class("Face recognition");
116 unsigned int loop_count = 0;
117
118 cv::Mat image = cv::Mat(cv::Size(camera->pixel_width(), camera->pixel_height()), CV_8UC1, 3);
119
120 cv::Mat scaled_image =
121 cv::Mat(cv::Size(camera->pixel_width() / 2, camera->pixel_height() / 2), CV_8UC1, 3);
122
123 FacesClassifier *classifier = new FacesClassifier(cascade_file,
124 camera->pixel_width(),
125 camera->pixel_height(),
126 scaled_image,
127 1.2 /* scale factor */,
128 2 /* min neighbours */,
129 CV_HAAR_DO_CANNY_PRUNING);
130
131 unsigned char *display_buffer = (unsigned char *)malloc(camera->buffer_size());
132
133 ImageDisplay *display =
134 new ImageDisplay(camera->pixel_width(), camera->pixel_height(), "QA Faces Classifier");
135
136 Drawer *drawer = new Drawer();
137 drawer->set_buffer(display_buffer, camera->pixel_width(), camera->pixel_height());
138
139 SDL_Event redraw_event;
140 redraw_event.type = SDL_KEYUP;
141 redraw_event.key.keysym.sym = SDLK_SPACE;
142
143 SDL_PushEvent(&redraw_event);
144
145 bool quit = false;
146 while (!quit) {
147 SDL_Event event;
148 if (SDL_WaitEvent(&event)) {
149 switch (event.type) {
150 case SDL_QUIT: quit = true; break;
151
152 case SDL_KEYUP:
153 if (event.key.keysym.sym == SDLK_SPACE) {
154 camera->capture();
155
156 if (camera->buffer() != NULL) {
157 CvMatAdapter::convert_image_bgr(camera->buffer(), image);
158 image.resize(scaled_image.rows, cv::INTER_LINEAR);
159 memcpy(display_buffer, camera->buffer(), camera->buffer_size());
160
161 tt->ping_start(ttc_recognition);
162 std::list<ROI> *rois = classifier->classify();
163 tt->ping_end(ttc_recognition);
164
165 camera->dispose_buffer();
166
167 bool first = true;
168 for (std::list<ROI>::reverse_iterator i = rois->rbegin(); i != rois->rend(); ++i) {
169 if (first) {
170 drawer->set_color(127, 70, 200);
171 }
172 drawer->draw_rectangle(2 * i->start.x, 2 * i->start.y, 2 * i->width, 2 * i->height);
173 if (first) {
174 drawer->set_color(30, 30, 30);
175 first = false;
176 }
177 }
178
179 if (++loop_count % 15 == 0) {
180 tt->print_to_stdout();
181 }
182
183 display->show(display_buffer);
184 }
185
186 SDL_PushEvent(&redraw_event);
187 }
188
189 else if (event.key.keysym.sym == SDLK_ESCAPE) {
190 quit = true;
191 }
192
193 break;
194
195 default: break;
196 }
197 }
198 }
199
200 camera->stop();
201 camera->close();
202 delete camera;
203 delete display;
204 delete drawer;
205 free(display_buffer);
206 image.release();
207 scaled_image.release();
208 delete tt;
209 }
210
211 else {
212 printf("Usage: %s -h <Haar cascade file> -f <Image file as JPEG>\n", argv[0]);
213 printf(" or %s -h <Haar cascade file> -c <Camera argument string>\n", argv[0]);
214 exit(-1);
215 }
216
217 delete argp;
218}
219
220/// @endcond
Parse command line arguments.
Definition: argparser.h:64
const char * arg(const char *argn)
Get argument value.
Definition: argparser.cpp:177
bool has_arg(const char *argn)
Check if argument has been supplied.
Definition: argparser.cpp:165
Base class for exceptions in Fawkes.
Definition: exception.h:36
Time tracking utility.
Definition: tracker.h:37
Fawkes library namespace.