00001 /** 00002 \file Robots/LoBot/io/LoGrabber.H 00003 \brief The bastard step cousin to the IEEE1394grabber. 00004 00005 This file defines the lobot::LoGrabber class, which uses the libdc1394 00006 API directly to perform multi-grabs from multiple FireWire cameras. We 00007 could do this using the IEEE1394grabber class; unfortunately, that 00008 class has some weird bug that causes multi-grab operations to crash. 00009 00010 Specifically, when we have multiple FireWire cameras daisy-chained 00011 together, their sub-channel IDs will be 0, 1, 2, etc. Creating the 00012 requisite number of instances of IEEE1394grabber and then setting the 00013 "FrameGrabberSubChan" option/parameter for each of these instance to 00014 the appropriate sub-channel ID should work. However, somewhere along 00015 the line, all the instances end up using the same sub-channel ID 00016 (e.g., 1 or 2 or 0 or whatever). Then, the libdc1394 library complains 00017 when trying to initialize the same sub-channel more than once. 00018 00019 Ideally, we ought to fix IEEE1394grabber so that it works correctly. 00020 In the mean time, the lobot::LoGrabber class provides a quick 00021 workaround that allows multi-grabs to function. It implements pretty 00022 much the same functionality as IEEE1394grabber in almost the same 00023 manner, except that it isn't part of the ModelComponent hierarchy. Its 00024 interface is also more direct and vastly simplified. Thus its label as 00025 "the bastard step cousin to IEEE1394grabber." 00026 */ 00027 00028 // //////////////////////////////////////////////////////////////////// // 00029 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00030 // by the University of Southern California (USC) and the iLab at USC. // 00031 // See http://iLab.usc.edu for information about this project. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00034 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00035 // in Visual Environments, and Applications'' by Christof Koch and // 00036 // Laurent Itti, California Institute of Technology, 2001 (patent // 00037 // pending; application number 09/912,225 filed July 23, 2001; see // 00038 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00039 // //////////////////////////////////////////////////////////////////// // 00040 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00041 // // 00042 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00043 // redistribute it and/or modify it under the terms of the GNU General // 00044 // Public License as published by the Free Software Foundation; either // 00045 // version 2 of the License, or (at your option) any later version. // 00046 // // 00047 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00048 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00049 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00050 // PURPOSE. See the GNU General Public License for more details. // 00051 // // 00052 // You should have received a copy of the GNU General Public License // 00053 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00054 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00055 // Boston, MA 02111-1307 USA. // 00056 // //////////////////////////////////////////////////////////////////// // 00057 // 00058 // Primary maintainer for this file: Manu Viswanathan <mviswana at usc dot edu> 00059 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/io/LoGrabber.H $ 00060 // $Id: LoGrabber.H 11256 2009-05-30 01:46:10Z mviswana $ 00061 // 00062 00063 #ifndef LOBOT_GRABBER_DOT_H 00064 #define LOBOT_GRABBER_DOT_H 00065 00066 //---------------------- ALTERNATIVE DEFINITION ------------------------- 00067 00068 // In case libdc1394 and other IEEE-1394 libraries are missing 00069 #ifndef HAVE_IEEE1394 00070 00071 #include "Robots/LoBot/misc/LoExcept.H" 00072 #include "Robots/LoBot/misc/LoTypes.H" 00073 #include "Image/Dims.H" 00074 00075 namespace lobot { 00076 00077 struct Grabber { 00078 Grabber(int, const Dims&, float) ; 00079 ImageType grab() const {return ImageType() ;} 00080 Dims frameSize() const {return Dims(0,0) ;} 00081 float frameRate() const {return 0 ;} 00082 } ; 00083 00084 } // end of namespace encapsulating above empty definition 00085 00086 #else 00087 00088 //------------------------------ HEADERS -------------------------------- 00089 00090 // lobot headers 00091 #include "Robots/LoBot/config/LoDefaults.H" 00092 00093 #include "Robots/LoBot/misc/LoTypes.H" 00094 00095 // INVT video conversion support 00096 #include "Video/VideoFormat.H" 00097 00098 // INVT image support 00099 #include "Image/Dims.H" 00100 00101 // 1394 headers 00102 #include <libdc1394/dc1394_control.h> 00103 00104 // Standard C++ headers 00105 #include <utility> 00106 00107 //----------------------------- NAMESPACE ------------------------------- 00108 00109 namespace lobot { 00110 00111 //-------------------------- HELPER CLASSES ----------------------------- 00112 00113 // Defaults for various camera parameters 00114 #ifndef LOCP_DEFAULT_BRIGHTNESS 00115 #define LOCP_DEFAULT_BRIGHTNESS 32768 00116 #endif 00117 #ifndef LOCP_DEFAULT_EXPOSURE 00118 #define LOCP_DEFAULT_EXPOSURE 511 00119 #endif 00120 #ifndef LOCP_DEFAULT_SHARPNESS 00121 #define LOCP_DEFAULT_SHARPNESS 80 00122 #endif 00123 #ifndef LOCP_DEFAULT_WHITE_BALANCE_UB 00124 #define LOCP_DEFAULT_WHITE_BALANCE_UB 95 00125 #endif 00126 #ifndef LOCP_DEFAULT_WHITE_BALANCE_VR 00127 #define LOCP_DEFAULT_WHITE_BALANCE_VR 87 00128 #endif 00129 #ifndef LOCP_DEFAULT_HUE 00130 #define LOCP_DEFAULT_HUE 32768 00131 #endif 00132 #ifndef LOCP_DEFAULT_SATURATION 00133 #define LOCP_DEFAULT_SATURATION 90 00134 #endif 00135 #ifndef LOCP_DEFAULT_GAMMA 00136 #define LOCP_DEFAULT_GAMMA 1 00137 #endif 00138 #ifndef LOCP_DEFAULT_SHUTTER 00139 #define LOCP_DEFAULT_SHUTTER 6 00140 #endif 00141 #ifndef LOCP_DEFAULT_GAIN 00142 #define LOCP_DEFAULT_GAIN 87 00143 #endif 00144 00145 /// Camera parameters "packet" 00146 struct CameraParams { 00147 int brightness, exposure, sharpness ; 00148 int white_balance_ub, white_balance_vr ; 00149 int hue, saturation ; 00150 int gamma, shutter, gain ; 00151 00152 CameraParams(int bright = LOCP_DEFAULT_BRIGHTNESS, 00153 int exp = LOCP_DEFAULT_EXPOSURE, 00154 int sharp = LOCP_DEFAULT_SHARPNESS, 00155 int ub = LOCP_DEFAULT_WHITE_BALANCE_UB, 00156 int vr = LOCP_DEFAULT_WHITE_BALANCE_VR, 00157 int hu = LOCP_DEFAULT_HUE, 00158 int sat = LOCP_DEFAULT_SATURATION, 00159 int gam = LOCP_DEFAULT_GAMMA, 00160 int shut = LOCP_DEFAULT_SHUTTER, 00161 int gn = LOCP_DEFAULT_GAIN) ; 00162 } ; 00163 00164 //------------------------- CLASS DEFINITION ---------------------------- 00165 00166 /** 00167 \class lobot::Grabber 00168 \brief Allow multi-grab from multiple FireWire cameras. 00169 00170 This class is a bastard step cousin to IEEE1394grabber. Its raison 00171 d'etre is to allow grabbing frames simultaneously from multiple 00172 FireWire cameras. 00173 00174 To do this, we would usually just instantiate IEEE1394grabber the 00175 required number of times. For example, if we have three cameras, we 00176 would create three IEEE1394grabber instances and reconfigure them to 00177 use separate sub-channels. That is, one of the instance would use 00178 sub-channel 0 (first camera on the FireWire bus), the next one would 00179 use sub-channel 1 (second camera), and the third instance would use 00180 sub-channel 2. Unfortunately, at this time (circa October 2008), due 00181 to some strange bug, all the IEEE1394grabber instances end up using 00182 the same sub-channel (say, 1) even when the "FrameGrabberSubChan" 00183 option is explicitly reset. This causes the libdc1394 library to 00184 complain when each IEEE1394grabber tries to (re)initialize the same 00185 camera (i.e., sub-channel). 00186 00187 Obviously, the best thing to do is fix IEEE1394grabber, thus, making 00188 this class obsolete. But that requires a fair amount of familiarity 00189 with INVT internals (something the author of this class, circa October 00190 2008, does not yet possess). This class, therefore, serves as an 00191 interim solution. 00192 00193 It should be noted that whereas IEEE1394grabber is part of the 00194 ModelComponent hierarchy, lobot::Grabber is not. Internally, it is 00195 implemented almost identically to IEEE1394grabber. However, much of 00196 IEEE1394grabber's pizazz, generality and configurability are missing 00197 because this class is designed specifically for the Lobot/Robolocust 00198 project. Its interface is quite direct and simple. 00199 */ 00200 class Grabber { 00201 // Each grabber needs to remember the sub-channel ID of the camera it 00202 // is bound to (i.e., the camera number of the camera it is supposed 00203 // to grab images from). 00204 int m_camera_number ; 00205 00206 // For successful conversion between the image format returned by the 00207 // camera and the desired INVT Image type, we need to remember the 00208 // grab resolution. 00209 Dims m_grab_size ; 00210 00211 // Usually, cameras pack the image data they return based on the grab 00212 // resolution. For example, the Unibrain Fire-i returns frames in 00213 // YUV444 format when grabbing at 160x120 and YUV422 at 320x240. The 00214 // INVT framework provides handy functions/classes to convert such 00215 // "raw" frames to RGB images. However, the enums used by the 00216 // libdc1394 library and INVT are different. To keep things in sync, 00217 // we have to remember the appropriate enums for each. 00218 // 00219 // We do that with an STL pair whose first member holds the enum for 00220 // libdc1394 and whose second member stores the enum for INVT. 00221 std::pair<int, VideoFormat> m_grab_mode ; 00222 00223 // We also have to remember the libdc1394 enum for the grab frame 00224 // rate. 00225 int m_frame_rate ; 00226 00227 // Each grabber has its own capture buffer 00228 mutable dc1394_cameracapture m_capture ; 00229 00230 public : 00231 /// The constructor expects the sub-channel ID of the camera to grab 00232 /// from (i.e., the camera number). It can also take the size of the 00233 /// frame to be grabbed (defaults to 320x240), the frame rate 00234 /// (defaults to 30fps), and various camera parameters such as 00235 /// brightness, gamma, etc. (defaults should be okay). 00236 Grabber(int camera_number, 00237 const Dims& resolution = LOBOT_DEFAULT_GRAB_SIZE, 00238 float frame_rate = LOBOT_DEFAULT_GRAB_RATE, 00239 const CameraParams& params = CameraParams()) ; 00240 00241 /// Set various camera parameters 00242 void setParams(const CameraParams&) ; 00243 00244 /// After instantitation, clients may use this method to retrieve 00245 /// frames from the camera this grabber is bound to. 00246 ImageType grab() const ; 00247 00248 /// Return the size of the frames being grabbed 00249 Dims frameSize() const {return m_grab_size ;} 00250 00251 /// Return the rate at which frames are being grabbed from the source 00252 /// camera. 00253 float frameRate() const ; 00254 00255 /// Clean-up 00256 ~Grabber() ; 00257 } ; 00258 00259 //----------------------------------------------------------------------- 00260 00261 } // end of namespace encapsulating this file's definitions 00262 00263 #endif // #ifndef HAVE_IEEE1394 00264 #endif // #ifndef LOBOT_GRABBER_DOT_H 00265 00266 /* So things look consistent in everyone's emacs... */ 00267 /* Local Variables: */ 00268 /* indent-tabs-mode: nil */ 00269 /* End: */