camera.h
Go to the documentation of this file.00001 // -*-c++-*- 00002 //---------------------------< /-/ CLARAty /-/ >------------------------------ 00003 /** 00004 * @file camera.h 00005 * 00006 * Defines the base logical camera class. 00007 * 00008 * <br>@b Designer(s): Daniel Clouse, Clay Kunz, Issa Nesnas 00009 * <br>@b Author(s): Daniel Clouse 00010 * <br>@b Date: June 9, 2006 00011 * 00012 * <b>Software License:</b><br> 00013 * <code> http://claraty.jpl.nasa.gov/license/open_src/ or 00014 * file: license/open_src.txt </code> 00015 * 00016 * © 2006, Jet Propulsion Laboratory, California Institute of Technology<br> 00017 * © 2007, NASA Ames Research Center 00018 * 00019 * $Revision: 1.11 $ 00020 */ 00021 //----------------------------------------------------------------------------- 00022 00023 #ifndef CAMERA_H 00024 #define CAMERA_H 00025 00026 #include "claraty/share.h" // Time 00027 #include "claraty/device.h" 00028 #include "claraty/image.h" 00029 00030 #include "claraty/exception.h" 00031 00032 namespace claraty { 00033 00034 //----------------------------------------------------------------------------- 00035 /** 00036 * @defgroup hardware_pkg Hardware Package 00037 * 00038 * The CLARAty Hardware Package contains modules that relate directly 00039 * to the hardware. 00040 * 00041 */ 00042 //@{ 00043 //@} 00044 00045 //----------------------------------------------------------------------------- 00046 /** 00047 * @defgroup device Device 00048 * @ingroup hardware_pkg 00049 * 00050 * Image acquisition/Camera related classes. 00051 * 00052 * Both physical camera and logical cameras are derived from the Device 00053 * base class. A physical camera represents the state of the actual hardware. 00054 * Implementations are responsible for enforcing that no more than one 00055 * physical camera variable be constructed for each hardware camera. 00056 * 00057 * Camera is derived from Device, and is the base class for all logical 00058 * cameras. A logical camera represents the user's view of the camera state. 00059 * A change of state in one logical camera does not affect the state of 00060 * another logical camera, even if they both refer to the same piece of 00061 * hardware. A logical camera implementation is required to maintain a local 00062 * cache of logical camera state. The acquire member function performs an 00063 * atomic operation which both sets the physical camera state to match that 00064 * of the logical camera, and acquires a single image. 00065 * 00066 * A logical camera should not be shared between tasks. A physical camera 00067 * may be safely shared between tasks if each task constructs its own 00068 * logical camera and all access to the physical camera is via these 00069 * logical cameras. 00070 * 00071 * An algorithm may be written without knowledge of the type of Camera 00072 * being used: 00073 * 00074 * <code> 00075 * void my_algorithm(Camera & my_camera) { 00076 * Camera_Image<uint8_t> my_image; 00077 * my_camera.set_exposure(0.25); 00078 * my_camera.acquire(my_image); 00079 * ... 00080 * } 00081 * </code> 00082 * 00083 * We can then pass a specific implemenation to the algorithm: 00084 * 00085 * <code> 00086 * XYZ_HW_Camera hw_camera(0x0233432, 0x343); 00087 * XYZ_Camera my_logical_camera(hw_camera); 00088 * my_algorithm(my_logical_camera); 00089 * </code> 00090 * 00091 */ 00092 //@{ 00093 //@} 00094 00095 /** 00096 * @ingroup device 00097 * Camera class. 00098 */ 00099 //@{ 00100 //@} 00101 00102 00103 class Camera_Model; 00104 class Feature_Map; 00105 template <typename Pixel> class Camera_Image; 00106 00107 class Camera : public Device { 00108 friend class Camera_Group; 00109 00110 public: 00111 static const double DONT_CARE = -DOUBLE_EPSILON; 00112 00113 // Specifies the camera's image format. 00114 enum IMAGE_FORMAT { MONO8, // Image<uint8_t> 00115 YUV411, // Image<uint8_t> 00116 YUV422, // Image<uint8_t> 00117 YUV444, // Image<uint8_t> 00118 RGB8, // Image<uint8_t> 00119 MONO16, // Image<uint16_t> 00120 RGB16 }; // Image<uint16_t> 00121 00122 public: 00123 00124 // @name Constructor 00125 // @{ 00126 00127 Camera(const std::string & device_name = "def_cam", 00128 Camera_Model* camera_model_ptr = NULL); 00129 // @} 00130 00131 // @name Destructor 00132 // @{ 00133 00134 virtual ~Camera() 00135 { } 00136 // @} 00137 00138 // @name Observers / Mutators 00139 // @{ 00140 00141 void set_camera_model_ptr(Camera_Model * cm) {_camera_model_ptr = cm;} 00142 00143 const Camera_Model * get_camera_model_ptr() const 00144 { 00145 return _camera_model_ptr; 00146 } 00147 00148 // gain_proportion is in range 0.0 .. 1.0 00149 // DONT_CARE means set to a default value and allow the value to be 00150 // changed by other tasks. 00151 virtual bool set_contrast(double gain_proportion = DONT_CARE) { return false; } 00152 virtual double get_contrast() const { return 1.0; } 00153 00154 // offset_proportion is in range 0.0 .. 1.0 00155 virtual bool set_brightness(double offset = DONT_CARE) { return false; } 00156 virtual double get_brightness() const { return 1.0; } 00157 virtual bool set_exposure (double seconds = DONT_CARE) { return false; } 00158 virtual double get_exposure () const { return 1.0; } 00159 00160 // Setting width_pixels or height_pixels to -1 means no change. 00161 virtual bool set_format(IMAGE_FORMAT format, 00162 int width_pixels = -1, 00163 int height_pixels = -1) { return false; } 00164 virtual IMAGE_FORMAT get_format() const { return MONO8; } 00165 00166 // Get_width and get_height return the number of pixels in the image as set 00167 // by set_format. Note that for many image formats, the number of pixels 00168 // is not the same as the number of elements in the image to be returned 00169 // from acquire. For example, an RGB format image has 3 times as many 00170 // elements as pixels. 00171 // Get_subframe_width and get_subframe_height return the number of pixels 00172 // in the image returned from acquire. If subframing is in effect 00173 // (see set_subframe), the number of pixels in the image will be less than 00174 // those set by set_format. 00175 virtual int get_width() const = 0; 00176 virtual int get_height() const = 0; 00177 00178 virtual bool set_subframe(int width_offset, 00179 int height_offset, 00180 int width, 00181 int height) { return false; } 00182 virtual int get_subframe_width_offset() const { return 0; } 00183 virtual int get_subframe_height_offset() const { return 0; } 00184 00185 // Always return the size of the image to be returned from acquire. 00186 // Note this implementation assumes subframes are not supported. 00187 virtual int get_subframe_width() const { return get_width(); }; 00188 virtual int get_subframe_height() const { return get_height(); }; 00189 00190 // @} 00191 00192 00193 // @name Acquisition 00194 // @{ 00195 00196 /** 00197 * @brief Acquire an Image (unsigned char version). 00198 * 00199 * A derived class must implement acquire with the following behavior: 00200 * 1. Verify that the the current image format (as set by set_format) is not one of 00201 * the 8 bit formats (MONO8, YUV411, YUV422, YUV444, RGB8), otherwise throw 00202 * invalid_argument. 00203 * 2. Set the physical camera parameter settings to match those of this 00204 * logical camera parameters. 00205 * 3. Resize the image to match the current camera format if necessary. 00206 * 4. Acquire an image from the physical camera. 00207 * 5. If *timestamp_ptr not NULL, fill with the time the image was acquired. 00208 * 6. If *feature_map_prt not NULL, fill with the camera parameter setting in 00209 * effect at the time the image was acquired. 00210 * 00211 * During this process any other error encountered causes an exception 00212 * derived from Camera_Exception to be thrown. 00213 * 00214 * @param[out] image 00215 * Returns newly acquired Image. The Image is resized to 00216 * match the image size returned by the camera. 00217 * @param[out] timestamp_ptr 00218 * If not NULL, returns time of image acquisition. 00219 * @param[out] feature_map_ptr 00220 * If not NULL, returns camera feature settings in effect 00221 * at image acquisition time. 00222 */ 00223 virtual void acquire(Image<uint8_t> & image, 00224 Time * timestamp_ptr = NULL, 00225 Feature_Map * feature_map_ptr = NULL) 00226 throw (std::exception) = 0; 00227 00228 /** 00229 * @brief Acquire an Image (unsigned short version). 00230 * 00231 * Behavior is the same as that of the unsigned char version except 00232 * that this version works with MONO16 and RGB16 formats only. 00233 */ 00234 virtual void acquire(Image<uint16_t> & image, 00235 Time * timestamp_ptr = NULL, 00236 Feature_Map * feature_map_ptr = NULL) 00237 throw (std::exception) = 0; 00238 00239 00240 template <class Pixel_Type> 00241 void acquire(Camera_Image<Pixel_Type> & image) throw (std::exception); 00242 00243 // @} 00244 00245 virtual bool io(FDM_Map map); 00246 00247 protected: 00248 void _verify_pixel_format(size_t pixel_size); 00249 00250 template <class Pixel_Type> 00251 void _verify_resize_image (Image<Pixel_Type> & image); 00252 00253 protected: 00254 Camera_Model * _camera_model_ptr; 00255 }; 00256 00257 std::ostream & operator << (std::ostream & os, const Camera & rhs); 00258 00259 //----------------------------------------------------------------------------- 00260 //----------------------------------------------------------------------------- 00261 /** 00262 * @brief Acquire a Camera_Image (template version). 00263 * 00264 * Acquire a Camera_Image using the current feature settings from this 00265 * logical camera. This routine may fail for a number of reasons. In 00266 * particular, it fails if the Pixel_Type of the image parameter does 00267 * not match that expected by the camera, as controlled by the 00268 * set_format member function. On failure, an exception is thrown. 00269 * 00270 * @param[out] image 00271 * Returns newly acquired Camera_Image. The image is 00272 * resized to match the image size returned by the camera. 00273 * The timestamp, and feature_map portions of the 00274 * Camera_Image are updated by this routine. The 00275 * camera_model portion of the Camera_Image returns the 00276 * Camera_Model as set by the Camera constructor or 00277 * set_camera_model_ptr(). 00278 */ 00279 template <class Pixel_Type> 00280 void 00281 Camera::acquire(Camera_Image<Pixel_Type> &image) throw (std::exception) 00282 { 00283 // Camera must be a friend of Camera_Image; requires change in Camera_Image 00284 acquire(image, &image._timestamp, &image._feature_map); 00285 image._frame_num = 0; 00286 } 00287 00288 //----------------------------------------------------------------------------- 00289 /** 00290 * Verify that the image size matches the camera frame size. If the image 00291 * size does not match the camera frame size, this function will resize 00292 * the image to the proper camera frame size. 00293 * 00294 * @param[in] image reference to an image object to be resized 00295 */ 00296 template<class Pixel_Type> 00297 void Camera:: 00298 _verify_resize_image(Image<Pixel_Type> & image) 00299 { 00300 if ((image.get_width () != get_width()) && 00301 (image.get_height() != get_height())) 00302 image.resize(get_height(), get_width()); 00303 } 00304 00305 //----------------------------------------------------------------------------- 00306 00307 /** 00308 * @} 00309 * @} 00310 */ 00311 00312 } // namespace claraty 00313 00314 #endif // CAMERA_H