Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * scale_viewer.cpp - Generic scale viewer tool 00004 * 00005 * Created: Thu Aug 25 16:13:34 2011 (based on fvviewer) 00006 * Copyright 2005-2011 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU Library General Public License for more details. 00019 * 00020 * Read the full text in the LICENSE.GPL file in the doc directory. 00021 */ 00022 00023 00024 #include <core/exceptions/software.h> 00025 #include <utils/system/argparser.h> 00026 #include <utils/time/tracker.h> 00027 00028 #include <fvcams/factory.h> 00029 #ifdef HAVE_SHMEM_CAM 00030 #include <fvcams/shmem.h> 00031 #endif 00032 #ifdef HAVE_NETWORK_CAM 00033 #include <fvcams/net.h> 00034 #endif 00035 #ifdef HAVE_FILELOADER_CAM 00036 #include <fvcams/fileloader.h> 00037 #endif 00038 00039 #include <cstring> 00040 #include <cstdio> 00041 #include <stdint.h> 00042 00043 #include <gtkmm.h> 00044 00045 #include <fvutils/color/conversions.h> 00046 00047 using namespace fawkes; 00048 using namespace firevision; 00049 00050 Gtk::Image *img_image; 00051 Camera *cam; 00052 00053 TimeTracker tt; 00054 int ttc_capture; 00055 int ttc_convert; 00056 int ttc_draw; 00057 int ttc_interloop; 00058 unsigned int loop_count = 0; 00059 00060 static bool 00061 timeout_handler() 00062 { 00063 tt.ping_end(ttc_interloop); 00064 00065 tt.ping_start(ttc_capture); 00066 cam->capture(); 00067 tt.ping_end(ttc_capture); 00068 00069 tt.ping_start(ttc_convert); 00070 unsigned int orig_width = cam->pixel_width(); 00071 unsigned int orig_height = cam->pixel_height(); 00072 00073 unsigned char *rgb_buffer = malloc_buffer(RGB, orig_width, orig_height); 00074 00075 convert(cam->colorspace(), RGB, cam->buffer(), rgb_buffer, 00076 orig_width, orig_height); 00077 tt.ping_end(ttc_convert); 00078 00079 tt.ping_start(ttc_draw); 00080 Glib::RefPtr<Gdk::Pixbuf> image = 00081 Gdk::Pixbuf::create_from_data( rgb_buffer, Gdk::COLORSPACE_RGB, false, 00082 8, orig_width, orig_height, 3 * orig_width); 00083 00084 int width = img_image->get_width(); 00085 int height = img_image->get_height(); 00086 Glib::RefPtr<Gdk::Pixbuf> scaled = image->scale_simple(width, height, 00087 Gdk::INTERP_NEAREST); 00088 00089 img_image->set(scaled); 00090 img_image->queue_draw(); 00091 00092 tt.ping_end(ttc_draw); 00093 00094 cam->dispose_buffer(); 00095 00096 free(rgb_buffer); 00097 00098 if (++loop_count >= 10) { 00099 loop_count = 0; 00100 tt.print_to_stdout(); 00101 } 00102 00103 tt.ping_start(ttc_interloop); 00104 return true; 00105 } 00106 00107 00108 00109 void 00110 print_usage(const char *program_name) 00111 { 00112 printf("Usage: %s -n host[:port]/image_id [-j] [-d delay] [-v]\n\n" 00113 " -n net_string Open network camera, the camera string is of the form\n" 00114 " host[:port]/image_id. You have to specify at least the host\n" 00115 " and the image_id, the port is optional and defaults to 5000\n" 00116 " -j Receive JPEG images, only valid with -n\n" 00117 " -d delay Delay in ms before a new image is capture.\n", 00118 program_name); 00119 } 00120 00121 00122 00123 int 00124 main(int argc, char **argv) 00125 { 00126 ArgumentParser argp(argc, argv, "hn:jd:"); 00127 00128 Gtk::Main gtk_main(argc, argv); 00129 00130 //bool verbose = argp.has_arg("v"); 00131 int delay = 300; 00132 00133 if ( argp.has_arg("d") ) { 00134 delay = atoi(argp.arg("d")); 00135 if ( delay < 0 ) delay = 300; 00136 } 00137 00138 if ( argp.has_arg("h") ) { 00139 print_usage(argp.program_name()); 00140 exit(0); 00141 } else if ( argp.has_arg("n") ) { 00142 char *net_string = strdup(argp.arg("n")); 00143 char *image_id = NULL, *host = NULL, *port = NULL, *save_ptr = NULL; 00144 int port_num = 2208; 00145 char *hostport; 00146 00147 hostport = strtok_r(net_string, "/", &save_ptr); 00148 image_id = strtok_r(NULL, "", &save_ptr); 00149 00150 if ( strchr(hostport, ':') != NULL ) { 00151 host = strtok_r(hostport, ":", &save_ptr); 00152 port = strtok_r(NULL, "", &save_ptr); 00153 } else { 00154 host = hostport; 00155 } 00156 00157 if ( port != NULL ) { 00158 port_num = atoi(port); 00159 if ( (port_num < 0) || (port_num > 0xFFFF) ) { 00160 throw OutOfBoundsException("Invalid port", port_num, 0, 0xFFFF); 00161 } 00162 } 00163 00164 if( image_id == NULL ) { 00165 throw IllegalArgumentException("Image ID must be specified"); 00166 } 00167 00168 cam = new NetworkCamera(host, port_num, image_id, argp.has_arg("j")); 00169 free(net_string); 00170 } else { 00171 print_usage(argp.program_name()); 00172 exit(1); 00173 } 00174 00175 try { 00176 cam->open(); 00177 cam->start(); 00178 } catch (Exception &e) { 00179 printf("Failed to open camera\n"); 00180 e.print_trace(); 00181 delete cam; 00182 exit(-2); 00183 } 00184 00185 ttc_capture = tt.add_class("Capture"); 00186 ttc_convert = tt.add_class("Convert"); 00187 ttc_draw = tt.add_class("Draw"); 00188 ttc_interloop = tt.add_class("InterLoop"); 00189 tt.ping_start(ttc_interloop); 00190 00191 Glib::RefPtr<Gtk::Builder> builder; 00192 builder = 00193 Gtk::Builder::create_from_file(RESDIR"/guis/scale_viewer/scale_viewer.ui"); 00194 00195 Gtk::Window *window; 00196 00197 builder->get_widget("wnd_main", window); 00198 builder->get_widget("img_image", img_image); 00199 00200 Glib::signal_timeout().connect(sigc::ptr_fun(&timeout_handler), delay); 00201 00202 window->set_size_request(320, 240); 00203 Gtk::Main::run(*window); 00204 00205 cam->close(); 00206 delete cam; 00207 00208 return 0; 00209 } 00210