23 #include <core/exceptions/software.h>
24 #include <fvcams/buffer.h>
25 #include <fvcams/factory.h>
26 #include <utils/system/argparser.h>
28 # include <fvcams/shmem.h>
30 #ifdef HAVE_NETWORK_CAM
31 # include <fvcams/net.h>
33 #ifdef HAVE_FILELOADER_CAM
34 # include <fvcams/fileloader.h>
37 #include <fvwidgets/image_display.h>
39 # include <fvfilters/rectify.h>
40 # include <fvutils/rectification/rectfile.h>
41 # include <fvutils/rectification/rectinfo_block.h>
43 #include <fvutils/colormap/cmfile.h>
44 #include <fvutils/colormap/colormap.h>
45 #include <fvutils/system/filetype.h>
55 #include <fvutils/color/conversions.h>
58 using namespace firevision;
61 print_usage(
const char *program_name)
63 printf(
"Usage: %s [-c] [-s shmem_id] [-n host[:port]/image_id] [-f file] [-o shmem_id] [-v] \\\n"
64 " [-d delay] [cam arg string]\n\n"
65 " -c Start in continuous update mode\n"
66 " -s shmem_id Open shared memory image with given ID\n"
67 " -n net_string Open network camera, the camera string is of the form\n"
68 " host[:port]/image_id. You have to specify at least the host\n"
69 " and the image_id, the port is optional and defaults to 5000\n"
70 " -j Receive JPEG images, only valid with -n\n"
71 " -d delay Delay in ms before a new image is capture.\n"
72 " -f file Open file loader camera with given file (image, colormap)\n"
73 " -o shmem_id Output the image to a shared memory segment with given ID\n"
74 " -v Verbose output on console\n"
75 " cam arg string Can be an arbitrary camera argument string that is understood\n"
76 " by CameraFactory and the desired camera.\n",
84 " c Toggle continuous mode (automatic image updating as fast as possible)\n"
85 " r rectify image, will query for rectification info file and possibly\n"
86 " for camera if there is more than one block.\n"
87 " + Increase delay by 5 ms\n"
88 " - Decrease delay by 5 ms\n"
89 " Shift-R rectify image, use already loaded lut info file, do not query for\n"
91 " Space Refresh image\n"
92 " q/Esc Quit viewer\n");
99 while (Gtk::Main::events_pending()) {
100 Gtk::Main::iteration();
105 main(
int argc,
char **argv)
108 std::string title =
"";
111 Gtk::Main gtk_main(argc, argv);
116 bool verbose = argp.has_arg(
"v");
119 unsigned int colormap_y = 0;
121 if (argp.has_arg(
"d")) {
122 delay = atoi(argp.arg(
"d"));
127 if (argp.has_arg(
"h")) {
128 print_usage(argp.program_name());
130 }
else if (argp.has_arg(
"s")) {
131 #ifdef HAVE_SHMEM_CAM
132 title = std::string(argp.arg(
"s"));
135 throw Exception(
"SharedMemoryCamera not available at compile time");
137 }
else if (argp.has_arg(
"f")) {
138 #ifdef HAVE_FILELOADER_CAM
139 std::string filename = argp.arg(
"f");
140 title = std::string(
"File: ").append(filename);
141 std::string ft = fv_filetype_file(filename.c_str());
143 if (ft ==
"FvColormap") {
145 cm_file.
read(filename.c_str());
154 throw Exception(
"FileLoader not available at compile time");
156 }
else if (argp.has_arg(
"n")) {
157 #ifdef HAVE_NETWORK_CAM
158 title = std::string(
"Net cam: ").append(argp.arg(
"n"));
159 char *net_string = strdup(argp.arg(
"n"));
160 char *image_id = NULL, *host = NULL, *port = NULL, *save_ptr = NULL;
164 hostport = strtok_r(net_string,
"/", &save_ptr);
165 image_id = strtok_r(NULL,
"", &save_ptr);
167 if (strchr(hostport,
':') != NULL) {
168 host = strtok_r(hostport,
":", &save_ptr);
169 port = strtok_r(NULL,
"", &save_ptr);
175 port_num = atoi(port);
176 if ((port_num < 0) || (port_num > 0xFFFF)) {
181 if (image_id == NULL) {
185 cam =
new NetworkCamera(host, port_num, image_id, argp.has_arg(
"j"));
188 throw Exception(
"NetworkCamera not available at compile time");
191 if (argp.num_items() == 0) {
192 print_usage(argp.program_name());
193 printf(
"\n\nNeither camera option nor camera string given. Aborting.\n\n");
196 cam = CameraFactory::instance(argp.items()[0]);
200 throw Exception(
"Failed to initialize camera for unknown reason");
207 printf(
"Failed to open camera\n");
213 if (argp.has_arg(
"o")) {
223 printf(
"Camera opened, settings:\n"
224 " Colorspace: %u (%s)\n"
225 " Dimensions: %u x %u\n"
226 " Buffer size: %zu\n"
241 unsigned char * filtered_buffer =
243 unsigned char *unfiltered_buffer =
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) {
260 case SDL_QUIT: quit =
true;
break;
262 if (event.key.keysym.sym == SDLK_SPACE) {
264 if (cam->
buffer() != NULL) {
278 rectify_filter->
apply();
279 display->show(YUV422_PLANAR, filtered_buffer);
289 printf(
"No valid frame received\n");
292 usleep(delay * 1000);
293 SDL_PushEvent(&redraw_event);
295 }
else if (event.key.keysym.sym == SDLK_ESCAPE) {
297 }
else if (event.key.keysym.sym == SDLK_q) {
299 }
else if (event.key.keysym.sym == SDLK_c) {
300 continuous = !continuous;
301 SDL_PushEvent(&redraw_event);
302 }
else if (event.key.keysym.sym == SDLK_PLUS) {
304 printf(
"New delay: %i ms\n", delay);
305 }
else if (event.key.keysym.sym == SDLK_MINUS) {
311 printf(
"New delay: %i ms\n", delay);
312 }
else if (event.key.keysym.sym == SDLK_UP) {
313 colormap_y = std::min(255u, colormap_y + 5);
314 printf(
"Colormap new Y (+): %u\n", colormap_y);
316 SDL_PushEvent(&redraw_event);
317 }
else if (event.key.keysym.sym == SDLK_DOWN) {
318 colormap_y = std::max(0, (
int)colormap_y - 5);
319 printf(
"Colormap new Y (-): %u\n", colormap_y);
321 SDL_PushEvent(&redraw_event);
322 }
else if (event.key.keysym.sym == SDLK_r) {
324 # ifdef HAVE_RECTINFO
328 if ((!(SDL_GetModState() & KMOD_LSHIFT) && !(SDL_GetModState() & KMOD_RSHIFT))
329 || !rectify_filter) {
330 Gtk::FileChooserDialog fcd(
"Open Rectification Info File");
333 fcd.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
334 fcd.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
336 # if GTK_VERSION_GE(3, 0)
337 Glib::RefPtr<Gtk::FileFilter> filter_rectinfo = Gtk::FileFilter::create();
338 filter_rectinfo->set_name(
"Rectification Info");
339 filter_rectinfo->add_pattern(
"*.rectinfo");
341 Gtk::FileFilter filter_rectinfo;
342 filter_rectinfo.set_name(
"Rectification Info");
343 filter_rectinfo.add_pattern(
"*.rectinfo");
345 fcd.add_filter(filter_rectinfo);
347 # if GTK_VERSION_GE(3, 0)
348 Glib::RefPtr<Gtk::FileFilter> filter_any = 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());
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();
382 Glib::ustring us = rectinfo_camera_strings[(*b)->camera()];
383 us += Glib::ustring(
" (") + rectinfo_type_strings[(*b)->type()] +
")";
384 # if GTK_VERSION_GE(3, 0)
387 cboxt.append_text(us);
392 Gtk::Dialog dialog(
"Choose Camera",
true);
393 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
394 dialog.get_vbox()->add(hbox);
398 process_gtk_events();
401 RectificationInfoFile::RectInfoBlockVector::iterator bi = blocks->begin();
402 for (
int i = 1; i < cboxt.get_active_row_number(); ++i) {
409 delete rectify_filter;
412 Gtk::MessageDialog md(e.
what(),
415 md.set_title(
"Reading Rectification Info failed");
419 process_gtk_events();
423 rectifying = (rectify_filter != NULL);
425 SDL_PushEvent(&redraw_event);
427 printf(
"Rectification support not available at compile time\n");
431 printf(
"Rectification support requires gtkmm(-devel) to be installed "
432 " at compile time.\n");
442 delete rectify_filter;
443 free(filtered_buffer);
444 free(unfiltered_buffer);
Parse command line arguments.
Base class for exceptions in Fawkes.
void print_trace() noexcept
Prints trace to stderr.
virtual const char * what() const noexcept
Get primary string.
Expected parameter is missing.
Simple buffer with a Camera interface.
Camera interface for image aquiring devices in FireVision.
virtual void close()=0
Close camera.
virtual unsigned int pixel_height()=0
Height of image in pixels.
virtual unsigned int buffer_size()=0
Size of buffer.
virtual void dispose_buffer()=0
Dispose current buffer.
virtual unsigned int pixel_width()=0
Width of image in pixels.
virtual void open()=0
Open the camera.
virtual void capture()=0
Capture an image.
virtual colorspace_t colorspace()=0
Colorspace of returned image.
virtual unsigned char * buffer()=0
Get access to current image buffer.
virtual void start()=0
Start image transfer from the camera.
Colormap * get_colormap()
Get a freshly generated colormap based on current file content.
virtual void to_image(unsigned char *yuv422_planar_buffer, unsigned int level=0)
Create image from LUT.
virtual void apply()
Apply the filter.
virtual void set_dst_buffer(unsigned char *buf, ROI *roi)
Set the destination buffer.
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.
virtual void read(const char *file_name)
Read file.
size_t num_blocks()
Get the number of available info blocks.
Rectification info block.
Vector that is used for maintaining the rectification info blocks.
virtual void read(const char *filename)
Read file.
RectInfoBlockVector * rectinfo_blocks()
Get all rectification info blocks.
Shared memory image buffer.
unsigned char * buffer() const
Get image buffer.
Fawkes library namespace.