24 #include <core/exceptions/software.h> 25 #include <utils/system/argparser.h> 27 #include <fvcams/factory.h> 28 #include <fvcams/buffer.h> 30 #include <fvcams/shmem.h> 32 #ifdef HAVE_NETWORK_CAM 33 #include <fvcams/net.h> 35 #ifdef HAVE_FILELOADER_CAM 36 #include <fvcams/fileloader.h> 39 #include <fvwidgets/image_display.h> 41 #include <fvutils/rectification/rectfile.h> 42 #include <fvutils/rectification/rectinfo_block.h> 43 #include <fvfilters/rectify.h> 45 #include <fvutils/colormap/colormap.h> 46 #include <fvutils/colormap/cmfile.h> 47 #include <fvutils/system/filetype.h> 58 #include <fvutils/color/conversions.h> 64 print_usage(
const char *program_name)
66 printf(
"Usage: %s [-c] [-s shmem_id] [-n host[:port]/image_id] [-f file] [-o shmem_id] [-v] \\\n" 67 " [-d delay] [cam arg string]\n\n" 68 " -c Start in continuous update mode\n" 69 " -s shmem_id Open shared memory image with given ID\n" 70 " -n net_string Open network camera, the camera string is of the form\n" 71 " host[:port]/image_id. You have to specify at least the host\n" 72 " and the image_id, the port is optional and defaults to 5000\n" 73 " -j Receive JPEG images, only valid with -n\n" 74 " -d delay Delay in ms before a new image is capture.\n" 75 " -f file Open file loader camera with given file (image, colormap)\n" 76 " -o shmem_id Output the image to a shared memory segment with given ID\n" 77 " -v Verbose output on console\n" 78 " cam arg string Can be an arbitrary camera argument string that is understood\n" 79 " by CameraFactory and the desired camera.\n",
87 " c Toggle continuous mode (automatic image updating as fast as possible)\n" 88 " r rectify image, will query for rectification info file and possibly\n" 89 " for camera if there is more than one block.\n" 90 " + Increase delay by 5 ms\n" 91 " - Decrease delay by 5 ms\n" 92 " Shift-R rectify image, use already loaded lut info file, do not query for\n" 94 " Space Refresh image\n" 95 " q/Esc Quit viewer\n");
103 while ( Gtk::Main::events_pending() ) {
104 Gtk::Main::iteration();
110 main(
int argc,
char **argv)
113 std::string title =
"";
116 Gtk::Main gtk_main(argc, argv);
121 bool verbose = argp.has_arg(
"v");
124 unsigned int colormap_y = 0;
126 if ( argp.has_arg(
"d") ) {
127 delay = atoi(argp.arg(
"d"));
128 if ( delay < 0 ) delay = 0;
131 if ( argp.has_arg(
"h") ) {
132 print_usage(argp.program_name());
134 }
else if ( argp.has_arg(
"s") ) {
135 #ifdef HAVE_SHMEM_CAM 136 title = std::string(argp.arg(
"s"));
139 throw Exception(
"SharedMemoryCamera not available at compile time");
141 }
else if ( argp.has_arg(
"f") ) {
142 #ifdef HAVE_FILELOADER_CAM 143 std::string filename = argp.arg(
"f");
144 title = std::string(
"File: ").append(filename);
145 std::string ft = fv_filetype_file(filename.c_str());
147 if (ft ==
"FvColormap") {
149 cm_file.
read(filename.c_str());
153 colormap->
to_image(cam->buffer(), colormap_y);
158 throw Exception(
"FileLoader not available at compile time");
160 }
else if ( argp.has_arg(
"n") ) {
161 #ifdef HAVE_NETWORK_CAM 162 title = std::string(
"Net cam: ").append(argp.arg(
"n"));
163 char *net_string = strdup(argp.arg(
"n"));
164 char *image_id = NULL, *host = NULL, *port = NULL, *save_ptr = NULL;
168 hostport = strtok_r(net_string,
"/", &save_ptr);
169 image_id = strtok_r(NULL,
"", &save_ptr);
171 if ( strchr(hostport,
':') != NULL ) {
172 host = strtok_r(hostport,
":", &save_ptr);
173 port = strtok_r(NULL,
"", &save_ptr);
178 if ( port != NULL ) {
179 port_num = atoi(port);
180 if ( (port_num < 0) || (port_num > 0xFFFF) ) {
185 if( image_id == NULL ) {
189 cam =
new NetworkCamera(host, port_num, image_id, argp.has_arg(
"j"));
192 throw Exception(
"NetworkCamera not available at compile time");
195 if ( argp.num_items() == 0 ) {
196 print_usage(argp.program_name());
197 printf(
"\n\nNeither camera option nor camera string given. Aborting.\n\n");
200 cam = CameraFactory::instance(argp.items()[0]);
204 throw Exception(
"Failed to initialize camera for unknown reason");
211 printf(
"Failed to open camera\n");
217 if ( argp.has_arg(
"o") )
225 printf(
"Camera opened, settings:\n" 226 " Colorspace: %u (%s)\n" 227 " Dimensions: %u x %u\n" 228 " Buffer size: %zu\n" 230 cam->colorspace(), colorspace_to_string(cam->colorspace()),
231 cam->pixel_width(), cam->pixel_height(),
232 colorspace_buffer_size(cam->colorspace(), cam->pixel_width(), cam->pixel_height()),
241 unsigned char *filtered_buffer = malloc_buffer(YUV422_PLANAR,
242 cam->pixel_width(), cam->pixel_height());
243 unsigned char *unfiltered_buffer = malloc_buffer(YUV422_PLANAR,
244 cam->pixel_width(), cam->pixel_height());
245 bool rectifying =
false;
247 bool continuous = argp.has_arg(
"c");
249 SDL_Event redraw_event;
250 redraw_event.type = SDL_KEYUP;
251 redraw_event.key.keysym.sym = SDLK_SPACE;
253 SDL_PushEvent(&redraw_event);
258 if ( SDL_WaitEvent(&event) ) {
259 switch (event.type) {
264 if ( event.key.keysym.sym == SDLK_SPACE ) {
266 if (cam->buffer() != NULL ) {
267 if ( buf ) memcpy(buf->
buffer(), cam->buffer(), cam->buffer_size());
270 convert(cam->colorspace(), YUV422_PLANAR, cam->buffer(), unfiltered_buffer,
271 cam->pixel_width(), cam->pixel_height());
272 ROI *fir = ROI::full_image(cam->pixel_width(), cam->pixel_height());
275 rectify_filter->
apply();
276 display->
show(YUV422_PLANAR, filtered_buffer);
279 display->
show(cam->colorspace(), cam->buffer());
284 cam->dispose_buffer();
286 printf(
"No valid frame received\n");
289 usleep(delay * 1000);
290 SDL_PushEvent(&redraw_event);
292 }
else if ( event.key.keysym.sym == SDLK_ESCAPE ) {
294 }
else if ( event.key.keysym.sym == SDLK_q ) {
296 }
else if ( event.key.keysym.sym == SDLK_c ) {
297 continuous = ! continuous;
298 SDL_PushEvent(&redraw_event);
299 }
else if ( event.key.keysym.sym == SDLK_PLUS ) {
301 printf(
"New delay: %i ms\n", delay);
302 }
else if ( event.key.keysym.sym == SDLK_MINUS ) {
308 printf(
"New delay: %i ms\n", delay);
309 }
else if ( event.key.keysym.sym == SDLK_UP ) {
310 colormap_y = std::min(255u, colormap_y + 5);
311 printf(
"Colormap new Y (+): %u\n", colormap_y);
312 colormap->
to_image(cam->buffer(), colormap_y);
313 SDL_PushEvent(&redraw_event);
314 }
else if ( event.key.keysym.sym == SDLK_DOWN ) {
315 colormap_y = std::max(0, (
int)colormap_y - 5);
316 printf(
"Colormap new Y (-): %u\n", colormap_y);
317 colormap->
to_image(cam->buffer(), colormap_y);
318 SDL_PushEvent(&redraw_event);
319 }
else if ( event.key.keysym.sym == SDLK_r ) {
321 # ifdef HAVE_RECTINFO 325 if ( (! (SDL_GetModState() & KMOD_LSHIFT) &&
326 ! (SDL_GetModState() & KMOD_RSHIFT)) ||
328 Gtk::FileChooserDialog fcd(
"Open Rectification Info File");
331 fcd.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
332 fcd.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
334 #if GTK_VERSION_GE(3,0) 335 Glib::RefPtr<Gtk::FileFilter> filter_rectinfo =
336 Gtk::FileFilter::create();
337 filter_rectinfo->set_name(
"Rectification Info");
338 filter_rectinfo->add_pattern(
"*.rectinfo");
340 Gtk::FileFilter filter_rectinfo;
341 filter_rectinfo.set_name(
"Rectification Info");
342 filter_rectinfo.add_pattern(
"*.rectinfo");
344 fcd.add_filter(filter_rectinfo);
346 #if GTK_VERSION_GE(3,0) 347 Glib::RefPtr<Gtk::FileFilter> filter_any =
348 Gtk::FileFilter::create();
349 filter_any->set_name(
"Any File");
350 filter_any->add_pattern(
"*");
352 Gtk::FileFilter filter_any;
353 filter_any.set_name(
"Any File");
354 filter_any.add_pattern(
"*");
356 fcd.add_filter(filter_any);
358 int result = fcd.run();
361 process_gtk_events();
363 if ( result == Gtk::RESPONSE_OK) {
366 rectfile->read(fcd.get_filename().c_str());
367 if ( rectfile->num_blocks() == 0 ) {
368 throw Exception(
"Rectification info file does not contain any info blocks");
371 Gtk::Label label(
"Camera: ");
372 Gtk::ComboBoxText cboxt;
379 for (RectificationInfoFile::RectInfoBlockVector::iterator b = blocks->begin(); b != blocks->end(); ++b) {
380 Glib::ustring us = rectinfo_camera_strings[(*b)->camera()];
381 us += Glib::ustring(
" (") + rectinfo_type_strings[(*b)->type()] +
")";
382 #if GTK_VERSION_GE(3,0) 385 cboxt.append_text(us);
390 Gtk::Dialog dialog(
"Choose Camera",
true);
391 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
392 dialog.get_vbox()->add(hbox);
396 process_gtk_events();
399 RectificationInfoFile::RectInfoBlockVector::iterator bi = blocks->begin();
400 for(
int i = 1; i < cboxt.get_active_row_number(); ++i) {
406 delete rectify_filter;
409 Gtk::MessageDialog md(e.
what(),
412 md.set_title(
"Reading Rectification Info failed");
416 process_gtk_events();
420 rectifying = (rectify_filter != NULL);
422 SDL_PushEvent(&redraw_event);
424 printf(
"Rectification support not available at compile time\n");
428 printf(
"Rectification support requires gtkmm(-devel) to be installed " 429 " at compile time.\n");
440 delete rectify_filter;
441 free(filtered_buffer);
442 free(unfiltered_buffer);
virtual void to_image(unsigned char *yuv422_planar_buffer, unsigned int level=0)
Create image from LUT.
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.
virtual const char * what() const
Get primary string.
Colormap * get_colormap()
Get a freshly generated colormap based on current file content.
Vector that is used for maintaining the rectification info blocks.
unsigned char * buffer() const
Get image buffer.
virtual void read(const char *file_name)
Read file.
Simple buffer with a Camera interface.
Base class for exceptions in Fawkes.
Shared memory 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.