latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*---------------------------------------------------------------- 00025 * project ....: LTI Digital Image/Signal Processing Library 00026 * file .......: ltiGrayWorldNormalization.h 00027 * authors ....: Suat Akyol,Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 8.11.2000 00030 * revisions ..: $Id: ltiGrayWorldNormalization.h,v 1.10 2006/02/08 11:13:49 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_GRAY_WORLD_NORMALIZATION_H_ 00034 #define _LTI_GRAY_WORLD_NORMALIZATION_H_ 00035 00036 #include "ltiImage.h" 00037 #include "ltiColorNormalizationBase.h" 00038 00039 namespace lti { 00040 /** 00041 * Performs a color normalization on an lti::image using a gray 00042 * world approach, in order to eliminate effects of illumination 00043 * colour. 00044 * 00045 * Gray world methods and white world methods assume that some low order 00046 * statistics on the colors of a real world scene lie on the gray line of 00047 * a color space. The most simple approach uses only the mean color and 00048 * maps it linearly into one specific point on the gray line, assuming 00049 * that a diagonal transform (a simple channel scaling) is valid. 00050 * 00051 * Normalization is done under the assumptiomn of mondrian worlds, 00052 * constant point light sources and delta function camera sensors. 00053 * 00054 * For each color channel \f$c\in{r,g,b}\f$, the normalization will be 00055 * \f[ 00056 * c_n \rightarrow \frac{c} 00057 * {(1-\gamma) + \gamma(\nu \cdot c_\mu + \kappa \cdot c_\sigma)} 00058 *\f] 00059 * 00060 * With: 00061 * - \f$\gamma\f$: normalization strength between 0 (no normalization) and 00062 * 1 (complete normalization). 00063 * - \f$c_\mu\f$: mean value of the \e c channel. 00064 * - \f$c_\sigma\f$: standard deviation of the \e c channel. 00065 * - \f$\nu\f$: mean value scaling factor. 00066 * - \f$\kappa\f$: standard deviation scaling factor. 00067 * 00068 * Initial theory: Diploma Thesis, Dipl.-Ing. Jose Pablo Alvarado Moya, 1998 00069 * Dept. of Technical Computer Science, RWTH Aachen, Germany. 00070 * 00071 * \ingroup gColor 00072 */ 00073 class grayWorldNormalization : public colorNormalizationBase { 00074 public: 00075 /** 00076 * The parameters for the class grayWorldNormalization. 00077 * 00078 * This class provides mainly the parameters to implement the 00079 * normalization equation: 00080 * 00081 * \f[ 00082 * c_n \rightarrow \frac{c} 00083 * {(1-\gamma) + \gamma(\nu \cdot c_\mu + \kappa \cdot c_\sigma)} 00084 *\f] 00085 * 00086 * With: 00087 * - \f$c_\mu\f$: mean value of the \e c channel. 00088 * - \f$c_\sigma\f$: standard deviation of the \e c channel. 00089 * - \f$\gamma\f$: normalization strength between 0 (no normalization) and 00090 * 1 (complete normalization) (gamma) 00091 * - \f$\nu\f$: mean value scaling factor (nu). 00092 * - \f$\kappa\f$: standard deviation scaling factor (kappa). 00093 */ 00094 class parameters : public colorNormalizationBase::parameters { 00095 public: 00096 /** 00097 * default constructor 00098 */ 00099 parameters(); 00100 00101 /** 00102 * copy constructor 00103 * @param other the parameters object to be copied 00104 */ 00105 parameters(const parameters& other); 00106 00107 /** 00108 * destructor 00109 */ 00110 ~parameters(); 00111 00112 /** 00113 * returns name of this type 00114 */ 00115 const char* getTypeName() const; 00116 00117 /** 00118 * copy the contents of a parameters object 00119 * @param other the parameters object to be copied 00120 * @return a reference to this parameters object 00121 */ 00122 parameters& copy(const parameters& other); 00123 00124 /** 00125 * returns a pointer to a clone of the parameters 00126 */ 00127 virtual functor::parameters* clone() const; 00128 00129 /** 00130 * write the parameters in the given ioHandler 00131 * @param handler the ioHandler to be used 00132 * @param complete if true (the default) the enclosing begin/end will 00133 * be also written, otherwise only the data block will be written. 00134 * @return true if write was successful 00135 */ 00136 virtual bool write(ioHandler& handler,const bool complete=true) const; 00137 00138 /** 00139 * write the parameters in the given ioHandler 00140 * @param handler the ioHandler to be used 00141 * @param complete if true (the default) the enclosing begin/end will 00142 * be also written, otherwise only the data block will be written. 00143 * @return true if write was successful 00144 */ 00145 virtual bool read(ioHandler& handler,const bool complete=true); 00146 00147 # ifdef _LTI_MSC_6 00148 /** 00149 * this function is required by MSVC only, as a workaround for a 00150 * very awful bug, which exists since MSVC V.4.0, and still by 00151 * V.6.0 with all bugfixes (so called "service packs") remains 00152 * there... This method is public due to another bug, so please 00153 * NEVER EVER call this method directly: use read() instead! 00154 */ 00155 bool readMS(ioHandler& handler,const bool complete=true); 00156 00157 /** 00158 * this function is required by MSVC only, as a workaround for a 00159 * very awful bug, which exists since MSVC V.4.0, and still by 00160 * V.6.0 with all bugfixes (so called "service packs") remains 00161 * there... This method is public due to another bug, so please 00162 * NEVER EVER call this method directly: use write() instead! 00163 */ 00164 bool writeMS(ioHandler& handler,const bool complete=true) const; 00165 # endif 00166 00167 // ------------------------------------------------ 00168 // the parameters 00169 // ------------------------------------------------ 00170 00171 /** 00172 * @name Computation of normalization constant. 00173 */ 00174 //@{ 00175 00176 /** 00177 * Scaling factor for the standard deviation. 00178 * 00179 * Default = 3.0 00180 */ 00181 float kappa; 00182 00183 /** 00184 * Scaling factor for the channel mean. 00185 * 00186 * Default value: 1 00187 */ 00188 float nu; 00189 00190 /** 00191 * Some times a "total" normalization will damage the color information 00192 * in a way, that this cannot be used in recognition processes. In order 00193 * to avoid to strong normalizations, this gamma factor can be used. 00194 * Its value MUST be between 0 and 1. 0 means no normalization at all 00195 * and 1 the best normalization to be achieved. 00196 * 00197 * Default value: 1 00198 */ 00199 float gamma; 00200 00201 //@} 00202 00203 /** 00204 * @name General options 00205 */ 00206 //@{ 00207 /** 00208 * Flag to indicate if a specific color should be ignored (true) 00209 * or if the whole image should be considered to determine the 00210 * normalization factors (false). Please note that this flag 00211 * will have effect if and only if the localNormalization is 00212 * deactivated! 00213 * 00214 * Default value: false 00215 */ 00216 bool ignoreColorFlag; 00217 00218 /** 00219 * This color will be ignored in the computations of the norm, if 00220 * the ignoreColorFlag is true. This way, the background can be ignored 00221 * if it was "markt" with a specific color (usually black). 00222 * 00223 * Default value: rgbPixel(0,0,0) (Black) 00224 */ 00225 rgbPixel ignoreColor; 00226 00227 /** 00228 * default is false. Set this to true, if you want to allow 00229 * overflow values in the normalized channels. Otherwise over- 00230 * and underflows will be set to the allowed max resp. min 00231 * values. 00232 */ 00233 bool allowOverflow; 00234 //@} 00235 00236 /** 00237 * @name Local normalization 00238 */ 00239 //@{ 00240 /** 00241 * if true, the normalization constants are computed for each pixel 00242 * using the given window size. If false, only one normalization 00243 * constant is used for the whole image. 00244 * 00245 * Default: false 00246 */ 00247 bool localNormalization; 00248 00249 /** 00250 * Window size specify the neighbourhood to be considered in the 00251 * computations of the normalization factors. This element has 00252 * effect only if <code>localInvariance</code> is true. 00253 * 00254 * Default value: 64; 00255 */ 00256 int windowSize; 00257 //@} 00258 00259 }; 00260 00261 /** 00262 * default constructor 00263 */ 00264 grayWorldNormalization(); 00265 00266 /** 00267 * default constructor 00268 */ 00269 grayWorldNormalization(const parameters& par); 00270 00271 /** 00272 * copy constructor 00273 * @param other the object to be copied 00274 */ 00275 grayWorldNormalization(const grayWorldNormalization& other); 00276 00277 /** 00278 * destructor 00279 */ 00280 virtual ~grayWorldNormalization(); 00281 00282 /** 00283 * returns the name of this type ("grayWorldNormalization") 00284 */ 00285 virtual const char* getTypeName() const; 00286 00287 /** 00288 * operates on the given %parameter. 00289 * @param srcdest image with the source data. 00290 * The result will be left here too. 00291 * @return true if successful, false otherwise. 00292 */ 00293 bool apply(image& srcdest) const; 00294 00295 /** 00296 * operates on a copy of the given %parameters. 00297 * @param src image with the source data. 00298 * @param dest image where the result will be left. 00299 * @return true if successful, false otherwise. 00300 */ 00301 bool apply(const image& src,image& dest) const; 00302 00303 /** 00304 * operates on a copy of the given %parameters. 00305 * @param srcR red channel of the source data 00306 * @param srcG green channel of the source data 00307 * @param srcB blue channel of the source data 00308 * @param dest image where the result will be left. 00309 * @return true if successful, false otherwise. 00310 */ 00311 bool apply(const channel& srcR, 00312 const channel& srcG, 00313 const channel& srcB, 00314 image& dest) const; 00315 00316 /** 00317 * operates on a copy of the given %parameters. 00318 * @param src image with the source data. 00319 * @param chR red component of the normalized input image. 00320 * @param chG green component of the normalized input image. 00321 * @param chB blue component of the normalized input image. 00322 * @return true if successful, false otherwise. 00323 */ 00324 bool apply(const image& src, 00325 channel& chR, 00326 channel& chG, 00327 channel& chB) const; 00328 00329 /** 00330 * operates on a copy of the given %parameters. 00331 * @param srcR red channel of the source data 00332 * @param srcG green channel of the source data 00333 * @param srcB blue channel of the source data 00334 * @param chR red component of the normalized input image. 00335 * @param chG green component of the normalized input image. 00336 * @param chB blue component of the normalized input image. 00337 * @return true if successful, false otherwise. 00338 */ 00339 bool apply(const channel& srcR, 00340 const channel& srcG, 00341 const channel& srcB, 00342 channel& chR, 00343 channel& chG, 00344 channel& chB) const; 00345 00346 /** 00347 * operates on the given %parameter. 00348 * @param srcdestR red channel of the source and destination. 00349 * @param srcdestG green channel of the source and destination. 00350 * @param srcdestB blue channel of the source and destination. 00351 * @return true if successful, false otherwise. 00352 */ 00353 bool apply(channel& srcdestR, 00354 channel& srcdestG, 00355 channel& srcdestB) const; 00356 00357 /** 00358 * copy data of "other" functor. 00359 * @param other the functor to be copied 00360 * @return a reference to this functor object 00361 */ 00362 grayWorldNormalization& copy(const grayWorldNormalization& other); 00363 00364 /** 00365 * returns a pointer to a clone of this functor. 00366 */ 00367 virtual functor* clone() const; 00368 00369 /** 00370 * returns used parameters 00371 */ 00372 const parameters& getParameters() const; 00373 00374 private: 00375 /** 00376 * ensure that the value x lies between a and b 00377 */ 00378 inline ubyte inChannel8Range(const float& x) const { 00379 return (x<=0.0f) ? 0: ((x>=255.0f) ? 255 : static_cast<ubyte>(x)); 00380 } 00381 00382 /** 00383 * ensure that the value x lies between a and b 00384 */ 00385 inline float inChannelRange(const float& x) const { 00386 return (x<0.0f) ? 0.0f : ((x>1.0f) ? 1.0f : x); 00387 } 00388 00389 /** 00390 * for the global method, compute the norm 00391 */ 00392 void computeNorm(const channel& red, 00393 const channel& green, 00394 const channel& blue, 00395 trgbPixel<float>& norm) const; 00396 00397 /** 00398 * for the global method, compute the norm 00399 */ 00400 void computeNorm(const image& img, 00401 trgbPixel<float>& norm) const; 00402 00403 /** 00404 * for the local method, compute the norm 00405 */ 00406 void computeNorm(const channel& red, 00407 const channel& green, 00408 const channel& blue, 00409 channel& normRed, 00410 channel& normGreen, 00411 channel& normBlue) const; 00412 00413 /** 00414 * compute the norm for one channel 00415 */ 00416 void computeNorm(const channel& chnl, 00417 channel& norm) const; 00418 00419 /** 00420 * normalize avoiding overflows 00421 */ 00422 void normalizeWithoutOverflow(const channel& input, 00423 const float& norm, 00424 channel& output) const; 00425 00426 /** 00427 * normalize image 00428 */ 00429 void normalize(image& img, const trgbPixel<float>& norm) const; 00430 00431 /** 00432 * normalize image 00433 */ 00434 void normalize(const image& img, 00435 const trgbPixel<float>& norm, 00436 image& dest) const; 00437 00438 00439 }; 00440 } 00441 00442 #endif