PixelsBase.H

Go to the documentation of this file.
00001 /*!@file Image/PixelsBase.H Basic pixel types version 2.0 */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: T. Nathan Mundhenk <mundhenk@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/PixelsBase.H $
00035 // $Id: PixelsBase.H 11146 2009-04-28 01:21:17Z itti $
00036 //
00037 
00038 #ifndef PIXELSBASE_H_DEFINED
00039 #define PIXELSBASE_H_DEFINED
00040 
00041 #include "Util/Types.H"
00042 #include "Util/TypeTraits.H"
00043 #include "Util/log.H"
00044 #include "Util/Promotions.H"
00045 #include <cmath>
00046 #include <cstdlib> // for size_t
00047 
00048 // ######################################################################
00049 // ######################################################################
00050 // Macros for overloading on base types
00051 // ######################################################################
00052 // ######################################################################
00053 
00054 //! Enumerate pixel types as a convenience
00055 enum PixType
00056 {
00057   PixTypeBase,
00058   PixTypeRGB,
00059   PixTypeHSV,
00060   PixTypeYUV,
00061   PixTypeYIQ,
00062   PixTypeHSL,
00063   PixTypeLab,
00064   PixTypeXYZ,
00065   PixTypeH2SV1,
00066   PixTypeH2SV2,
00067   PixTypeH2SV3,
00068   PixTypeHyper,
00069   PixTypeDKL,
00070 };
00071 
00072 // ######################################################################
00073 // ######################################################################
00074 // Range values for certain pixel types
00075 // ######################################################################
00076 // ######################################################################
00077 
00078 //! RGB ranges R Upper bound
00079 const int RGB_R_UPPER = 255;
00080 //! RGB ranges R Lower bound
00081 const int RGB_R_LOWER = 0;
00082 //! RGB ranges G Upper bound
00083 const int RGB_G_UPPER = 255;
00084 //! RGB ranges G Lower bound
00085 const int RGB_G_LOWER = 0;
00086 //! RGB ranges B Upper bound
00087 const int RGB_B_UPPER = 255;
00088 //! RGB ranges B Lower bound
00089 const int RGB_B_LOWER = 0;
00090 
00091 //! HSV Ranges H Upper bound
00092 const int HSV_H_UPPER = 360;
00093 //! HSV Ranges H Lower bound
00094 const int HSV_H_LOWER = 0;
00095 //! HSV Ranges S Upper bound
00096 const int HSV_S_UPPER = 100;
00097 //! HSV Ranges S Lower bound
00098 const int HSV_S_LOWER = 0;
00099 //! HSV Ranges V Upper bound
00100 const int HSV_V_UPPER = 255;
00101 //! HSV Ranges V Lower bound
00102 const int HSV_V_LOWER = 0;
00103 
00104 //! HSL Ranges H Upper bound
00105 const int HSL_H_UPPER = 360;
00106 //! HSL Ranges H Lower bound
00107 const int HSL_H_LOWER = 0;
00108 //! HSL Ranges S Upper bound
00109 const int HSL_S_UPPER = 1;
00110 //! HSL Ranges S Lower bound
00111 const int HSL_S_LOWER = 0;
00112 //! HSL Ranges V Upper bound
00113 const int HSL_L_UPPER = 1;
00114 //! HSL Ranges V Lower bound
00115 const int HSL_L_LOWER = 0;
00116 
00117 //! YUV ranges Y Upper bound
00118 const int YUV_Y_UPPER = 255;
00119 //! YUV ranges Y Lower bound
00120 const int YUV_Y_LOWER = 0;
00121 //! YUV ranges U Upper bound
00122 const int YUV_U_UPPER = 255;
00123 //! YUV ranges U Lower bound
00124 const int YUV_U_LOWER = 0;
00125 //! YUV ranges V Upper bound
00126 const int YUV_V_UPPER = 255;
00127 //! YUV ranges V Lower bound
00128 const int YUV_V_LOWER = 0;
00129 
00130 //! LAB ranges L Upper bound (Normalized to 0 - 255)
00131 const int LAB_L_UPPER = 255;
00132 //! LAB ranges L Lower bound
00133 const int LAB_L_LOWER = 0;
00134 //! LAB ranges A Upper bound (normalized from +/-128)
00135 const int LAB_A_UPPER = 255;
00136 //! LAB ranges A Lower bound
00137 const int LAB_A_LOWER = 0;
00138 //! LAB ranges B Upper bound (normalized from +/-128)
00139 const int LAB_B_UPPER = 255;
00140 //! LAB ranges B Lower bound
00141 const int LAB_B_LOWER = 0;
00142 
00143 //! H2SV ranges (all types) H1 Upper Bound
00144 const double H2SV_H1_UPPER = 1.0;
00145 //! H2SV ranges (all types) H1 Lower Bound
00146 const double H2SV_H1_LOWER = 0.0;
00147 //! H2SV ranges (all types) H2 Upper Bound
00148 const double H2SV_H2_UPPER = 1.0;
00149 //! H2SV ranges (all types) H2 Lower Bound
00150 const double H2SV_H2_LOWER = 0.0;
00151 //! H2SV ranges (all types) S Upper Bound
00152 const double H2SV_S_UPPER =  1.0;
00153 //! H2SV ranges (all types) S Lower Bound
00154 const double H2SV_S_LOWER =  0.0;
00155 //! H2SV ranges (all types) V Upper Bound
00156 const double H2SV_V_UPPER =  1.0;
00157 //! H2SV ranges (all types) V Lower Bound
00158 const double H2SV_V_LOWER =  0.0;
00159 
00160 // ######################################################################
00161 // ######################################################################
00162 // BASE PIXELS CLASS
00163 // ######################################################################
00164 // ######################################################################
00165 
00166 template <class T, size_t dim> class Pixels;
00167 
00168 //! Specialize TypeTraits to indicate that Pixels is a "trivial" type.
00169 template <class T, size_t dim>
00170 struct TypeTraits<Pixels<T,dim> >
00171 {
00172   enum { isTrivial = TypeTraits<T>::isTrivial };
00173 };
00174 
00175 //! This is the base Pixel class for a pixel of any size
00176 /*! This class contains all base operators and constructors to create
00177     a pixel of any size. To create specific pixel types (i.e. RGB HSV YUV)
00178     derive from this class then add the translation functions for typing
00179     and constructors.
00180 
00181     The base class is mainly used to contain the data and access it raw.
00182     Since data from one pixel to another needs to be converted and translated
00183     into a different space, all operations between pixels is handled at the
00184     level of the derived class to force compile time binding and to make sure
00185     that all bindings are handeled correctly.
00186 
00187     ********************************************
00188     All pixels have several constant attributes:
00189 
00190     const static enum PixType pType - This is an enumeration for the
00191                                       type of pixel this is
00192 
00193     const static size_t myDim - This is how many dimensions (dim) I
00194                                 have for the base class and hyper
00195                                 spectral pixels, this is contained in
00196                                 the template parameter dim at
00197                                 declaration.
00198 
00199     <size_t dim> - This is applied to Pixels and PixHyper at
00200                    declaration and contains the diminsion of this
00201                    pixel
00202 
00203     ******
00204     Notes:
00205 
00206     (1) size_t is used to hold dimension of the Pixel class. on a
00207         32-bit machine this means that any hyper spectral image is
00208         limited to 2^32 pixel componenets (which should be plenty!)
00209     (2) Any custom free function for pixels must be accompanied by another
00210         free form function for a base type to keep compatability.
00211         Thus, if you write a function getBent(Pixels<T>) you must also make
00212         a getBent(T) so that it can apply to either a basic type or a pixel
00213         type.
00214     (3) All pixel types must convert to and from PixRGB so that it can be
00215         used as a universal translation pixel type. That is, if you want
00216         to convert from type XYZ to ABC you do not need to know the direct
00217         translation so long as you can convert from XYZ to RGB and then
00218         to ABC.
00219     (4) All arithmetic between pixels must convert between color spaces
00220         while performing such operations. As such PixRGB = PixRGB + PixHSV
00221         will convert the third pixel to a PixRGB type then add it with
00222         second pixel this formula. Thus, conversion is implicite in the
00223         math. Additionally, all pixels must support such operations
00224         with basic types. So PixRGB = PixRGB + float must be supported
00225         as well.
00226 
00227    ******
00228    Files:
00229 
00230    (1) Pixels.H - This file contains the free math functions such as
00231                        sqrt(Pixel<T>). It also contains free functions
00232                        for the non-sense relational operators. If you
00233                        add a pixel type you will only need to make a
00234                        small change at then end by adding macros for
00235                        free math functions for your pixel with the
00236                        PIX_FREE_MATH_FUNCTIONS.
00237 
00238    (2) PixelsBase.H - This file. Contains the base class and its
00239                        methods.  If you add a pixel, you will not need
00240                        to change anything in this file.
00241 
00242    (3) PixelsTypes.H - This file contains the derived pixel classes as
00243                        well as other derived pixel type specific
00244                        information such as TypeTraits information for
00245                        each pixel and the static def for each pixels
00246                        temporary. This file as well as
00247                        PixelsTypesDefine will require the most change
00248                        if you add a new type of pixel
00249 
00250   (4) Promotions.H - This file contains a macro for creating the
00251                      proper promotions for basic1 types. Take a look at
00252                      it. If you add your own pixel type you may want
00253                      to add the promotions and type trait info
00254                      here. This is simple and recomended.
00255 
00256   (5) test-new-Pixels - This is a very simple binary to test to pixels
00257                         and make sure they work as they are supposed
00258                         to.
00259 
00260   ******************************
00261   Current supported Pixel Types:
00262 
00263   PixRGB<T> - This is a basic RGB pixel of 3 dimensions. All pixels
00264               must be able to convert to and from this type of pixel
00265               at the very minumum.
00266 
00267   PixHSV<T> - This is a standard HSV pixel type of three dimensions.
00268 
00269   PixJpegYUV<T> - This is a YUV pixel of three dimensions, using
00270                   YUV-for-JPEG conversion conventions.
00271 
00272   PixVideoYUV<T> - This is a YUV pixel of three dimensions, using
00273                    YUV-for-video (MPEG) conversion conventions.
00274 
00275   PixYIQ<T> - This is a YIQ pixel of three dimensions.
00276 
00277   PixHSL<T> - This is a standard HSL pixel (similar to HSV).
00278 
00279   PixH2SV1<T> - This is a pixel derived from HSV with the hue
00280                 demodulized.  It has four dimensions.
00281 
00282   PixH2SV2<T> - This is a pixel derived from HSV with the hue
00283                 demodulized.  It has four dimensions. It has a closer
00284                 resemblance, but a linear one to Red/Green Blue/Yellow
00285                 opponencie than H2SV1.
00286 
00287   PixH2SV3<T> - This is a pixel derived from HSV with the hue
00288                 demodulized.  It has four dimensions.  It has a closer
00289                 resemblance, but a non-linear one to Red/Green
00290                 Blue/Yellow opponencie than H2SV1.  It is currently in
00291                 the works.
00292 
00293   PixHyper<T,dim> - This is a hyper spectral pixel as large as 16^2
00294                     dimensions. Some operators are not supported on
00295                     this pixel type, but will be at a future date.
00296 
00297 */
00298 template <class T, size_t dim> class Pixels
00299 {
00300 private:
00301 protected:
00302 public:
00303 
00304   // ######################################################################
00305   // typedefs
00306 
00307   typedef T                                 ScalarType;
00308   typedef typename promote_trait<T,T>::TP   SelfPromoteType;
00309 
00310   // ######################################################################
00311   // Constuctors
00312 
00313   //! initalize an empty pixel
00314   inline Pixels();
00315   //! generic destructor
00316   inline ~Pixels();
00317   //! initalize a pixel with all cell values T
00318   inline Pixels(const Pixels<T,dim>& pix);
00319   //! initalize a pixel with all cell values T
00320   template <class T2> explicit inline Pixels(const Pixels<T2,dim>& pix);
00321   //! initalize a pixel with all cell values T
00322   explicit inline Pixels(const T* pix);
00323 
00324   //! initalize a pixel with all cell values T
00325   explicit inline Pixels(const T val);
00326 
00327   // ######################################################################
00328   /* DATA */
00329   //! pixel info array pointer
00330   T p[dim];
00331 
00332   const static enum PixType pType = PixTypeBase;
00333   const static size_t myDim = dim;
00334 
00335   // ######################################################################
00336   // Pixel Data Access Methods
00337 
00338   //! get the diminsion of this pixel
00339   inline size_t getDim();
00340   //! set the value of this pixel from another pixel, with no conversion
00341   template <class T2> inline void setVal(Pixels<T2,dim>& A);
00342   //! get a const array element in this pixel
00343   inline const T& operator[](const size_t item) const;
00344   //! get an array element in this pixel
00345   inline T& operator[](const size_t item);
00346   //! get functional access to a pixel element
00347   inline T& at(const size_t item);
00348 
00349   // ######################################################################
00350   // Pixel operators ==, !=
00351 
00352   //! Pixel equality operator
00353   inline bool operator==(const Pixels<T,dim>& A) const;
00354   //! Pixel inequality operator
00355   inline bool operator!=(const Pixels<T,dim>& A) const;
00356 
00357   // ######################################################################
00358   // Pixel operators ++, --
00359 
00360   //! Pixels ++ operator
00361   inline Pixels<T,dim> operator++();
00362   //! Pixels -- operator
00363   inline Pixels<T,dim> operator--();
00364 };
00365 
00366 // ######################################################################
00367 // ######################################################################
00368 // Actual Pixel class that holds pixel data
00369 // ######################################################################
00370 // ######################################################################
00371 // Class Pixels
00372 // ######################################################################
00373 // ######################################################################
00374 
00375 // ######################################################################
00376 // CONSTRUCTORS
00377 // ######################################################################
00378 template <class T, size_t dim>
00379 inline Pixels<T,dim>::Pixels()
00380 {
00381   for (size_t i = 0; i < dim; i++)
00382     p[i] = 0;
00383 }
00384 
00385 // ######################################################################
00386 template <class T, size_t dim>
00387 inline Pixels<T,dim>::~Pixels()
00388 {}
00389 
00390 // ######################################################################
00391 template <class T, size_t dim>
00392 inline Pixels<T,dim>::Pixels(const Pixels<T,dim>& pix)
00393 {
00394   for (size_t i = 0; i < dim; i++)
00395     p[i] = pix.p[i];
00396 }
00397 
00398 // ######################################################################
00399 template <class T, size_t dim>
00400 template <class T2> inline Pixels<T,dim>::Pixels(const Pixels<T2,dim>& pix)
00401 {
00402   for (size_t i = 0; i < dim; i++)
00403     p[i] = clamped_convert<T>(pix.p[i]);
00404 }
00405 
00406 // ######################################################################
00407 template <class T, size_t dim>
00408 inline Pixels<T,dim>::Pixels(const T* pix)
00409 {
00410   for (size_t i = 0; i < dim; i++)
00411     p[i] = pix[i];
00412 }
00413 
00414 // ######################################################################
00415 template <class T, size_t dim>
00416 inline Pixels<T,dim>::Pixels(const T val)
00417 {
00418   for (size_t i = 0; i < dim; i++)
00419     p[i] = val;
00420 }
00421 
00422 // ######################################################################
00423 // ACCESS METHODS
00424 // ######################################################################
00425 
00426 template <class T, size_t dim>
00427 inline size_t Pixels<T,dim>::getDim()
00428 {
00429   return dim;
00430 }
00431 
00432 // ######################################################################
00433 template <class T, size_t dim>
00434 template <class T2> inline void Pixels<T,dim>::setVal(Pixels<T2,dim>& A)
00435 {
00436   for (size_t i = 0; i < dim; i++)
00437     p[i] =  clamped_convert<T>(A[i]);
00438 }
00439 
00440 // ######################################################################
00441 template <class T, size_t dim>
00442 inline const T& Pixels<T,dim>::operator[](const size_t item) const
00443 {
00444   return p[item];
00445 }
00446 
00447 // ######################################################################
00448 template <class T, size_t dim>
00449 inline T& Pixels<T,dim>::operator[](const size_t item)
00450 {
00451   return p[item];
00452 }
00453 
00454 // ######################################################################
00455 template <class T, size_t dim>
00456 inline T& Pixels<T,dim>::at(const size_t item)
00457 {
00458   return p[item];
00459 }
00460 
00461 // ######################################################################
00462 // OPERATORS
00463 // ######################################################################
00464 
00465 template <class T, size_t dim>
00466 inline bool Pixels<T,dim>::operator==(const Pixels<T,dim>& A) const
00467 {
00468   bool ok = true;
00469   for (size_t i = 0; i < dim; i++)
00470     if(p[i] != A.p[i]) ok = false;
00471 
00472   return ok;
00473 }
00474 
00475 // ######################################################################
00476 template <class T, size_t dim>
00477 inline bool Pixels<T,dim>::operator!=(const Pixels<T,dim>& A) const
00478 {
00479   bool ok = false;
00480   for (size_t i = 0; i < dim; i++)
00481     if(p[i] != A.p[i]) ok = true;
00482   return ok;
00483 }
00484 
00485 // ######################################################################
00486 // INCR. OPERATORS
00487 // ######################################################################
00488 
00489 template <class T, size_t dim>
00490 inline Pixels<T,dim> Pixels<T,dim>::operator++()
00491 {
00492   for (size_t i = 0; i < dim; i++)
00493     p[i] = p[i] + 1;
00494   return *this;
00495 }
00496 
00497 // ######################################################################
00498 template <class T, size_t dim>
00499 inline Pixels<T,dim> Pixels<T,dim>::operator--()
00500 {
00501   for (size_t i = 0; i < dim; i++)
00502     p[i] = p[i] - 1;
00503   return *this;
00504 }
00505 
00506 namespace pix_helper
00507 {
00508   //! Transform this data into something more printable.
00509   /*! For example, convert char->int so that the char gets printed as
00510     a integer, rather than an alphabetic character. */
00511   inline bool printable(bool val) { return val;}
00512   inline int printable(char val) { return static_cast<int>(val);}
00513   inline short printable(short val) { return val;}
00514   inline int printable(int val) { return val;}
00515   inline long printable(long val) { return val;}
00516   inline float printable(float val) { return val;}
00517   inline double printable(double val) { return val;}
00518   inline long double printable(long double val) { return val;}
00519   inline int printable(unsigned char val) { return static_cast<int>(val);}
00520   inline int printable(unsigned short val) { return static_cast<int>(val);}
00521   inline long printable(unsigned int val) { return static_cast<long>(val);}
00522   inline unsigned long printable(unsigned long val) { return val;}
00523 }
00524 
00525 
00526 // ######################################################################
00527 // ######################################################################
00528 // inline free functions for stream input/output
00529 // ######################################################################
00530 // ######################################################################
00531 
00532 // ######################################################################
00533 //! << operator for pixels with use of Image_IO.C
00534 template <class T, size_t dim, class Ostream>
00535 inline Ostream&
00536 operator<<(Ostream& os, const Pixels<T,dim>& pixel)
00537 {
00538   os << '(';
00539 
00540   for (size_t i = 0; i < dim - 1; i++)
00541     os << pix_helper::printable(pixel.p[i]) << ", ";
00542 
00543   os << pix_helper::printable(pixel.p[dim - 1]) << ')';
00544 
00545   return os;
00546 }
00547 
00548 // ######################################################################
00549 //! >> operator for pixels
00550 template <class T, size_t dim, class Istream>
00551 inline Istream&
00552 operator>>(Istream& is, Pixels<T,dim>& pixel)
00553 {
00554   for (size_t i = 0; i < dim; i++)
00555     is >> pixel.p[i];
00556 
00557   return is;
00558 }
00559 
00560 // ######################################################################
00561 /* So things look consistent in everyone's emacs... */
00562 /* Local Variables: */
00563 /* indent-tabs-mode: nil */
00564 /* End: */
00565 
00566 #endif
Generated on Sun May 8 08:40:56 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3