24 #include <core/exceptions/software.h>
25 #include <utils/system/argparser.h>
27 #include <fvcams/factory.h>
29 #include <fvcams/shmem.h>
31 #ifdef HAVE_NETWORK_CAM
32 #include <fvcams/net.h>
34 #ifdef HAVE_FILELOADER_CAM
35 #include <fvcams/fileloader.h>
38 #include <fvwidgets/image_display.h>
40 #include <fvutils/rectification/rectfile.h>
41 #include <fvutils/rectification/rectinfo_block.h>
42 #include <fvfilters/rectify.h>
54 #include <fvutils/color/conversions.h>
60 print_usage(
const char *program_name)
62 printf(
"Usage: %s [-c] [-s shmem_id] [-n host[:port]/image_id] [-f file] [-o shmem_id] [-v] \\\n"
63 " [-d delay] [cam arg string]\n\n"
64 " -c Start in continuous update mode\n"
65 " -s shmem_id Open shared memory image with given ID\n"
66 " -n net_string Open network camera, the camera string is of the form\n"
67 " host[:port]/image_id. You have to specify at least the host\n"
68 " and the image_id, the port is optional and defaults to 5000\n"
69 " -j Receive JPEG images, only valid with -n\n"
70 " -d delay Delay in ms before a new image is capture.\n"
71 " -f file Open file loader camera with given file (image, colormap)\n"
72 " -o shmem_id Output the image to a shared memory segment with given ID\n"
73 " -v Verbose output on console\n"
74 " cam arg string Can be an arbitrary camera argument string that is understood\n"
75 " by CameraFactory and the desired camera.\n",
83 " c Toggle continuous mode (automatic image updating as fast as possible)\n"
84 " r rectify image, will query for rectification info file and possibly\n"
85 " for camera if there is more than one block.\n"
86 " + Increase delay by 5 ms\n"
87 " - Decrease delay by 5 ms\n"
88 " Shift-R rectify image, use already loaded lut info file, do not query for\n"
90 " Space Refresh image\n"
91 " q/Esc Quit viewer\n");
99 while ( Gtk::Main::events_pending() ) {
100 Gtk::Main::iteration();
106 main(
int argc,
char **argv)
109 std::string title =
"";
112 Gtk::Main gtk_main(argc, argv);
117 bool verbose = argp.has_arg(
"v");
120 if ( argp.has_arg(
"d") ) {
121 delay = atoi(argp.arg(
"d"));
122 if ( delay < 0 ) delay = 0;
125 if ( argp.has_arg(
"h") ) {
126 print_usage(argp.program_name());
128 }
else if ( argp.has_arg(
"s") ) {
129 #ifdef HAVE_SHMEM_CAM
130 title = std::string(argp.arg(
"s"));
133 throw Exception(
"SharedMemoryCamera not available at compile time");
135 }
else if ( argp.has_arg(
"f") ) {
136 #ifdef HAVE_FILELOADER_CAM
137 title = std::string(
"File: ").append(argp.arg(
"f"));
140 throw Exception(
"FileLoader not available at compile time");
142 }
else if ( argp.has_arg(
"n") ) {
143 #ifdef HAVE_NETWORK_CAM
144 title = std::string(
"Net cam: ").append(argp.arg(
"n"));
145 char *net_string = strdup(argp.arg(
"n"));
146 char *image_id = NULL, *host = NULL, *port = NULL, *save_ptr = NULL;
150 hostport = strtok_r(net_string,
"/", &save_ptr);
151 image_id = strtok_r(NULL,
"", &save_ptr);
153 if ( strchr(hostport,
':') != NULL ) {
154 host = strtok_r(hostport,
":", &save_ptr);
155 port = strtok_r(NULL,
"", &save_ptr);
160 if ( port != NULL ) {
161 port_num = atoi(port);
162 if ( (port_num < 0) || (port_num > 0xFFFF) ) {
167 if( image_id == NULL ) {
171 cam =
new NetworkCamera(host, port_num, image_id, argp.has_arg(
"j"));
174 throw Exception(
"NetworkCamera not available at compile time");
177 if ( argp.num_items() == 0 ) {
178 print_usage(argp.program_name());
179 printf(
"\n\nNeither camera option nor camera string given. Aborting.\n\n");
182 cam = CameraFactory::instance(argp.items()[0]);
186 throw Exception(
"Failed to initialize camera for unknown reason");
193 printf(
"Failed to open camera\n");
199 if ( argp.has_arg(
"o") )
207 printf(
"Camera opened, settings:\n"
208 " Colorspace: %u (%s)\n"
209 " Dimensions: %u x %u\n"
210 " Buffer size: %zu\n"
212 cam->colorspace(), colorspace_to_string(cam->colorspace()),
213 cam->pixel_width(), cam->pixel_height(),
214 colorspace_buffer_size(cam->colorspace(), cam->pixel_width(), cam->pixel_height()),
223 unsigned char *filtered_buffer = malloc_buffer(YUV422_PLANAR,
224 cam->pixel_width(), cam->pixel_height());
225 unsigned char *unfiltered_buffer = malloc_buffer(YUV422_PLANAR,
226 cam->pixel_width(), cam->pixel_height());
227 bool rectifying =
false;
229 bool continuous = argp.has_arg(
"c");
231 SDL_Event redraw_event;
232 redraw_event.type = SDL_KEYUP;
233 redraw_event.key.keysym.sym = SDLK_SPACE;
235 SDL_PushEvent(&redraw_event);
240 if ( SDL_WaitEvent(&event) ) {
241 switch (event.type) {
246 if ( event.key.keysym.sym == SDLK_SPACE ) {
248 if (cam->buffer() != NULL ) {
249 if ( buf ) memcpy(buf->
buffer(), cam->buffer(), cam->buffer_size());
252 convert(cam->colorspace(), YUV422_PLANAR, cam->buffer(), unfiltered_buffer,
253 cam->pixel_width(), cam->pixel_height());
254 ROI *fir = ROI::full_image(cam->pixel_width(), cam->pixel_height());
257 rectify_filter->
apply();
258 display->
show(YUV422_PLANAR, filtered_buffer);
261 display->
show(cam->colorspace(), cam->buffer());
266 cam->dispose_buffer();
268 printf(
"No valid frame received\n");
271 usleep(delay * 1000);
272 SDL_PushEvent(&redraw_event);
274 }
else if ( event.key.keysym.sym == SDLK_ESCAPE ) {
276 }
else if ( event.key.keysym.sym == SDLK_q ) {
278 }
else if ( event.key.keysym.sym == SDLK_c ) {
279 continuous = ! continuous;
280 SDL_PushEvent(&redraw_event);
281 }
else if ( event.key.keysym.sym == SDLK_PLUS ) {
283 printf(
"New delay: %i ms\n", delay);
284 }
else if ( event.key.keysym.sym == SDLK_MINUS ) {
290 printf(
"New delay: %i ms\n", delay);
291 }
else if ( event.key.keysym.sym == SDLK_r ) {
293 # ifdef HAVE_RECTINFO
297 if ( (! (SDL_GetModState() & KMOD_LSHIFT) &&
298 ! (SDL_GetModState() & KMOD_RSHIFT)) ||
300 Gtk::FileChooserDialog fcd(
"Open Rectification Info File");
303 fcd.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
304 fcd.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
306 #if GTK_VERSION_GE(3,0)
307 Glib::RefPtr<Gtk::FileFilter> filter_rectinfo =
308 Gtk::FileFilter::create();
309 filter_rectinfo->set_name(
"Rectification Info");
310 filter_rectinfo->add_pattern(
"*.rectinfo");
312 Gtk::FileFilter filter_rectinfo;
313 filter_rectinfo.set_name(
"Rectification Info");
314 filter_rectinfo.add_pattern(
"*.rectinfo");
316 fcd.add_filter(filter_rectinfo);
318 #if GTK_VERSION_GE(3,0)
319 Glib::RefPtr<Gtk::FileFilter> filter_any =
320 Gtk::FileFilter::create();
321 filter_any->set_name(
"Any File");
322 filter_any->add_pattern(
"*");
324 Gtk::FileFilter filter_any;
325 filter_any.set_name(
"Any File");
326 filter_any.add_pattern(
"*");
328 fcd.add_filter(filter_any);
330 int result = fcd.run();
333 process_gtk_events();
335 if ( result == Gtk::RESPONSE_OK) {
338 rectfile->read(fcd.get_filename().c_str());
339 if ( rectfile->num_blocks() == 0 ) {
340 throw Exception(
"Rectification info file does not contain any info blocks");
343 Gtk::Label label(
"Camera: ");
344 Gtk::ComboBoxText cboxt;
351 for (RectificationInfoFile::RectInfoBlockVector::iterator b = blocks->begin(); b != blocks->end(); ++b) {
352 Glib::ustring us = rectinfo_camera_strings[(*b)->camera()];
353 us += Glib::ustring(
" (") + rectinfo_type_strings[(*b)->type()] +
")";
354 #if GTK_VERSION_GE(3,0)
357 cboxt.append_text(us);
362 Gtk::Dialog dialog(
"Choose Camera",
true);
363 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
364 dialog.get_vbox()->add(hbox);
368 process_gtk_events();
371 RectificationInfoFile::RectInfoBlockVector::iterator bi = blocks->begin();
372 for(
int i = 1; i < cboxt.get_active_row_number(); ++i) {
378 delete rectify_filter;
381 Gtk::MessageDialog md(e.
what(),
384 md.set_title(
"Reading Rectification Info failed");
388 process_gtk_events();
392 rectifying = (rectify_filter != NULL);
394 SDL_PushEvent(&redraw_event);
396 printf(
"Rectification support not available at compile time\n");
400 printf(
"Rectification support requires gtkmm(-devel) to be installed "
401 " at compile time.\n");
412 delete rectify_filter;
413 free(filtered_buffer);
414 free(unfiltered_buffer);
Camera interface for image aquiring devices in FireVision.
virtual void set_src_buffer(unsigned char *buf, ROI *roi, orientation_t ori=ORI_HORIZONTAL, unsigned int buffer_num=0)
Set source buffer with orientation.
Fawkes library namespace.
Parse command line arguments.
Vector that is used for maintaining the rectification info blocks.
virtual const char * what() const
Get primary string.
Base class for exceptions in Fawkes.
Shared memory image buffer.
unsigned char * buffer() const
Get image buffer.
Rectification info block.
void print_trace()
Prints trace to stderr.
virtual void apply()
Apply the filter.
Expected parameter is missing.
void show(colorspace_t colorspace, unsigned char *buffer)
Show image from given colorspace.
virtual void set_dst_buffer(unsigned char *buf, ROI *roi)
Set the destination buffer.