Follow this link to skip to the main content

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  * &copy; 2006, Jet Propulsion Laboratory, California Institute of Technology<br>
00017  * &copy; 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