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