latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 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-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiColorContrastGradient.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 1.6.2003 00030 * revisions ..: $Id: ltiColorContrastGradient.h,v 1.16 2006/02/07 18:37:46 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_COLOR_CONTRAST_GRADIENT_H_ 00034 #define _LTI_COLOR_CONTRAST_GRADIENT_H_ 00035 00036 #include "ltiGradientFunctor.h" 00037 00038 namespace lti { 00039 /** 00040 * The contrast gradient is used in color or multi-spectral image as 00041 * a replacement of the gray-value gradient in gray images. 00042 * 00043 * Here, the approach introduced in A. Cumani, 00044 * "Edge Detection in Multispectral Images", Technical Report, 00045 * Istituto Elettrotecnico Nazionale "Galileo Ferraris", 1989 is 00046 * followed. 00047 * 00048 * A more detail theoretical analysis can be found in 00049 * I.R. Greenshields 00050 * "Coherent computation of the multispectral maximal directional derivative" 00051 * Image and Vision Computing, 00052 * Vol 18. 1999, pp. 1-7 00053 * 00054 * With this approach, instead of a gradient, the maximum of the contrast 00055 * function for each pixel is searched. The contrast function defines the 00056 * direction at the (x,y) plane at which the contrast change is maximal. It 00057 * corresponds to the greater eigenvalue and corresponding eigenvector of 00058 * the square of the Jacobian matrix: 00059 * 00060 * \f[ 00061 * \begin{pmatrix} 00062 * \frac{\partial \mathbf{f}}{\partial x}\cdot 00063 * \frac{\partial \mathbf{f}}{\partial x} & 00064 * \frac{\partial \mathbf{f}}{\partial x}\cdot 00065 * \frac{\partial \mathbf{f}}{\partial y} \\ 00066 * \frac{\partial \mathbf{f}}{\partial x}\cdot 00067 * \frac{\partial \mathbf{f}}{\partial y} & 00068 * \frac{\partial \mathbf{f}}{\partial y}\cdot 00069 * \frac{\partial \mathbf{f}}{\partial y} \\ 00070 * \end{pmatrix} 00071 * \f] 00072 * 00073 * As suggested in the literature, the difference between both eigenvalues 00074 * should be used as contrast, and the direction of the main eigenvector 00075 * as gradient direction. 00076 * 00077 * with \f$\mathbf{f}(x,y)\f$ being any multi-spectral image. In 00078 * this case this vector function is defined in a three dimensional color 00079 * space. 00080 * 00081 * Since this method uses the lti::arctanLUT class to accelerate the 00082 * computation (sacrifying a little bit in angle precision, which anyway 00083 * cannot be accurately determined due to the spatial quantization effects) 00084 * the angles returned in the parameters::Polar mode are always possitive 00085 * between 0 and 2*Pi. 00086 */ 00087 class colorContrastGradient : public gradientFunctor { 00088 public: 00089 /** 00090 * the parameters for the class gradientFunctor 00091 */ 00092 class parameters : public gradientFunctor::parameters { 00093 public: 00094 /** 00095 * default constructor 00096 */ 00097 parameters(); 00098 00099 /** 00100 * copy constructor 00101 * @param other the parameters object to be copied 00102 */ 00103 parameters(const parameters& other); 00104 00105 /** 00106 * destructor 00107 */ 00108 ~parameters(); 00109 00110 /** 00111 * returns name of this type 00112 */ 00113 const char* getTypeName() const; 00114 00115 /** 00116 * copy the contents of a parameters object 00117 * @param other the parameters object to be copied 00118 * @return a reference to this parameters object 00119 */ 00120 parameters& copy(const parameters& other); 00121 00122 /** 00123 * copy the contents of a parameters object 00124 * @param other the parameters object to be copied 00125 * @return a reference to this parameters object 00126 */ 00127 parameters& operator=(const parameters& other); 00128 00129 00130 /** 00131 * returns a pointer to a clone of the parameters 00132 */ 00133 virtual functor::parameters* clone() const; 00134 00135 /** 00136 * write the parameters in the given ioHandler 00137 * @param handler the ioHandler to be used 00138 * @param complete if true (the default) the enclosing begin/end will 00139 * be also written, otherwise only the data block will be written. 00140 * @return true if write was successful 00141 */ 00142 virtual bool write(ioHandler& handler,const bool complete=true) const; 00143 00144 /** 00145 * read the parameters from the given ioHandler 00146 * @param handler the ioHandler to be used 00147 * @param complete if true (the default) the enclosing begin/end will 00148 * be also written, otherwise only the data block will be written. 00149 * @return true if write was successful 00150 */ 00151 virtual bool read(ioHandler& handler,const bool complete=true); 00152 00153 # ifdef _LTI_MSC_6 00154 /** 00155 * this function is required by MSVC only, as a workaround for a 00156 * very awful bug, which exists since MSVC V.4.0, and still by 00157 * V.6.0 with all bugfixes (so called "service packs") remains 00158 * there... This method is also public due to another bug, so please 00159 * NEVER EVER call this method directly: use read() instead 00160 */ 00161 bool readMS(ioHandler& handler,const bool complete=true); 00162 00163 /** 00164 * this function is required by MSVC only, as a workaround for a 00165 * very awful bug, which exists since MSVC V.4.0, and still by 00166 * V.6.0 with all bugfixes (so called "service packs") remains 00167 * there... This method is also public due to another bug, so please 00168 * NEVER EVER call this method directly: use write() instead 00169 */ 00170 bool writeMS(ioHandler& handler,const bool complete=true) const; 00171 # endif 00172 00173 // ------------------------------------------------ 00174 // the parameters 00175 // ------------------------------------------------ 00176 00177 /** 00178 * Format types 00179 */ 00180 enum eContrastFormat { 00181 MDD, /**< Maximum Directional Derivative */ 00182 Contrast, /**< Difference between maximum and minimum eigenvalues */ 00183 Maximum /**< Maximum among all color channels */ 00184 }; 00185 00186 /** 00187 * The color gradient can be computed in several forms. 00188 * 00189 * The maximum directional derivative (MDD) is not exactly contrast, but 00190 * can provide a good edgeness measure. Its magnitude is the largest 00191 * eigenvalue of the Jacobian matrix. The direction of the maximum 00192 * directional derivative is used. 00193 * 00194 * The Contrast activates the real color contrast form, equal to the 00195 * difference of the eigenvalues of the square of the Jacobian matrix 00196 * for each pixel. 00197 * 00198 * The Maximum mode is not contrast any more. It just takes the 00199 * largest scalar gradient of each color channel. The angle of the 00200 * winner channel is used. 00201 * 00202 * Default value: Contrast 00203 */ 00204 eContrastFormat contrastFormat; 00205 }; 00206 00207 00208 /** 00209 * default constructor 00210 */ 00211 colorContrastGradient(); 00212 00213 /** 00214 * Construct a functor using gradient kernels with the specified values. 00215 * 00216 * @param format specify the format to be use: Cartesic or Polar 00217 * @param gradKernelSize size for the gradient kernel to be used. 00218 */ 00219 colorContrastGradient(const parameters::eOutputFormat& format, 00220 const int gradKernelSize=0); 00221 00222 /** 00223 * Construct a functor using the given parameters 00224 */ 00225 colorContrastGradient(const parameters& par); 00226 00227 /** 00228 * copy constructor 00229 * @param other the object to be copied 00230 */ 00231 colorContrastGradient(const colorContrastGradient& other); 00232 00233 /** 00234 * destructor 00235 */ 00236 virtual ~colorContrastGradient(); 00237 00238 /** 00239 * returns the name of this type ("colorContrastGradient") 00240 */ 00241 virtual const char* getTypeName() const; 00242 00243 /** 00244 * Computes the color contrast gradient of the given RGB image. 00245 * @param src image with the source data. The image will be splitted in 00246 * its R,G and B components for the analysis. 00247 * 00248 * @param xOrMag the resulting x component or magnitude of the gradient 00249 * will be left here. 00250 * @param yOrArg the resulting y component or argument (orientation) of 00251 * the gradient will be left here. 00252 * @return true if apply successful or false otherwise. 00253 */ 00254 bool apply(const image& src, 00255 channel& xOrMag, 00256 channel& yOrArg) const; 00257 00258 /** 00259 * Computes the (monochromatic) gradient of the given channel. 00260 * 00261 * @param src channel with the source data. 00262 * @param xOrMag the resulting x component or magnitude of the gradient 00263 * will be left here. 00264 * @param yOrArg the resulting y component or argument (orientation) of 00265 * the gradient will be left here. 00266 * @return true if apply successful or false otherwise. 00267 */ 00268 bool apply(const channel& src, 00269 channel& xOrMag, 00270 channel& yOrArg) const; 00271 00272 /** 00273 * Computes the (monochromatic) gradient of the given channel. 00274 * 00275 * @param src channel with the source data. 00276 * @param xOrMag the resulting x component or magnitude of the gradient 00277 * will be left here. 00278 * @param yOrArg the resulting y component or argument (orientation) of 00279 * the gradient will be left here. 00280 * @return true if apply successful or false otherwise. 00281 */ 00282 bool apply(const channel8& src, 00283 channel& xOrMag, 00284 channel& yOrArg) const; 00285 00286 /** 00287 * Computes the color contrast gradient of a tri-spectra image defined 00288 * by the three given components. 00289 * @param c1 first channel of the input image. 00290 * @param c2 second channel of the input image. 00291 * @param c3 third channel of the input image. 00292 * @param xOrMag the resulting x component or magnitude of the gradient 00293 * will be left here. 00294 * @param yOrArg the resulting y component or argument (orientation) of 00295 * the gradient will be left here. 00296 * @return true if apply successful or false otherwise. 00297 */ 00298 bool apply(const channel& c1, 00299 const channel& c2, 00300 const channel& c3, 00301 channel& xOrMag, 00302 channel& yOrArg) const; 00303 00304 /** 00305 * Computes the color contrast gradient of a tri-spectral image defined 00306 * by the three given components. 00307 * @param c1 first channel of the input image. 00308 * @param c2 second channel of the input image. 00309 * @param c3 third channel of the input image. 00310 * @param xOrMag the resulting x component or magnitude of the gradient 00311 * will be left here. 00312 * @param yOrArg the resulting y component or argument (orientation) of 00313 * the gradient will be left here. 00314 * @param maxMag if polar and cartesic modes (see parameters), the maximum 00315 * magnitude of the gradient found. 00316 * @return true if apply successful or false otherwise. 00317 */ 00318 bool apply(const channel& c1, 00319 const channel& c2, 00320 const channel& c3, 00321 channel& xOrMag, 00322 channel& yOrArg, 00323 float& maxMag) const; 00324 00325 /** 00326 * Computes the color contrast gradient of a bi-spectral image defined 00327 * by the two given components. 00328 * @param c1 first channel of the input image. 00329 * @param c2 second channel of the input image. 00330 * @param xOrMag the resulting x component or magnitude of the gradient 00331 * will be left here. 00332 * @param yOrArg the resulting y component or argument (orientation) of 00333 * the gradient will be left here. 00334 * @param maxMag if polar and cartesic modes (see parameters), the maximum 00335 * magnitude of the gradient found. 00336 * @return true if apply successful or false otherwise. 00337 */ 00338 bool apply(const channel& c1, 00339 const channel& c2, 00340 channel& xOrMag, 00341 channel& yOrArg, 00342 float& maxMag) const; 00343 00344 /** 00345 * Computes the eigenvalues of the square of the Jacobian matrix of a 00346 * tri-spectral image. 00347 * 00348 * This method ignores the parameter \a format, as it makes only sense for 00349 * a polar system, and also the \a contrastFormat parameter as it 00350 * explicitely requests the computation of all eigenvalues. 00351 * 00352 * @param c1 first channel of the input image. 00353 * @param c2 second channel of the input image. 00354 * @param c3 third channel of the input image. 00355 * @param lambdaMin the resulting minimal eigenvalues 00356 * @param lambdaMax the resulting maximal eigenvalues 00357 * @param orientation the angle of the main axis (diretion of the 00358 * eigenvector with the greater eigenvalue) 00359 * @param maxMag maximum contrast value found (lambdaMin-lambdaMax) 00360 * @return true if apply successful or false otherwise. 00361 */ 00362 bool apply(const channel& c1, 00363 const channel& c2, 00364 const channel& c3, 00365 channel& lambdaMin, 00366 channel& lambdaMax, 00367 channel& orientation, 00368 float& maxMag) const; 00369 00370 /** 00371 * copy data of "other" functor. 00372 * @param other the functor to be copied 00373 * @return a reference to this functor object 00374 */ 00375 colorContrastGradient& copy(const colorContrastGradient& other); 00376 00377 /** 00378 * alias for copy member 00379 * @param other the functor to be copied 00380 * @return a reference to this functor object 00381 */ 00382 colorContrastGradient& operator=(const colorContrastGradient& other); 00383 00384 /** 00385 * returns a pointer to a clone of this functor. 00386 */ 00387 virtual functor* clone() const; 00388 00389 /** 00390 * returns used parameters 00391 */ 00392 const parameters& getParameters() const; 00393 00394 protected: 00395 00396 /** 00397 * differentiate the image in X and Y directions 00398 * @param c1 first channel 00399 * @param c2 second channel 00400 * @param c3 third channel 00401 * @param gradAbs the absolute values of the gradient 00402 * @param orientation the orientation map of the gradient image 00403 * @param maxVal maximum value found in gradAbs 00404 * @return true if successful, false otherwise 00405 */ 00406 bool computeGradientPolar(const channel& c1, 00407 const channel& c2, 00408 const channel& c3, 00409 channel& gradAbs, 00410 channel& orientation, 00411 float& maxVal) const; 00412 00413 /** 00414 * differentiate the image in X and Y directions 00415 * @param c1 first channel 00416 * @param c2 second channel 00417 * @param gradAbs the absolute values of the gradient 00418 * @param orientation the orientation map of the gradient image 00419 * @param maxVal maximum value found in gradAbs 00420 * @return true if successful, false otherwise 00421 */ 00422 bool computeGradientPolar(const channel& c1, 00423 const channel& c2, 00424 channel& gradAbs, 00425 channel& orientation, 00426 float& maxVal) const; 00427 00428 /** 00429 * differentiate the image in X and Y directions 00430 * @param c1 first channel 00431 * @param c2 second channel 00432 * @param c3 third channel 00433 * @param lambdaMin minimum eigenvalues 00434 * @param lambdaMax maximum eigenvalues 00435 * @param orientation the orientation map of the gradient image 00436 * @param maxVal maximum contrast value found (lambdaMin-lambdaMax) 00437 * @return true if successful, false otherwise 00438 */ 00439 bool computeGradientPolar(const channel& c1, 00440 const channel& c2, 00441 const channel& c3, 00442 channel& lambdaMin, 00443 channel& lambdaMax, 00444 channel& orientation, 00445 float& maxVal) const; 00446 00447 00448 /** 00449 * differentiate the image in X and Y directions 00450 * @param c1 first channel 00451 * @param c2 second channel 00452 * @param xchnl x component 00453 * @param ychnl y component 00454 * @param maxVal maximum magnitude (max(sqrt(xchnl*xchnl+ychnl*ychnl)) 00455 * @return true if successful, false otherwise 00456 */ 00457 bool computeColorGradientCart(const channel& c1, 00458 const channel& c2, 00459 channel& xchnl, 00460 channel& ychnl, 00461 float& maxVal) const; 00462 00463 /** 00464 * differentiate the image in X and Y directions 00465 * @param c1 first channel 00466 * @param c2 second channel 00467 * @param c3 third channel 00468 * @param xchnl x component 00469 * @param ychnl y component 00470 * @param maxVal maximum magnitude (max(sqrt(xchnl*xchnl+ychnl*ychnl)) 00471 * @return true if successful, false otherwise 00472 */ 00473 bool computeColorGradientCart(const channel& c1, 00474 const channel& c2, 00475 const channel& c3, 00476 channel& xchnl, 00477 channel& ychnl, 00478 float& maxVal) const; 00479 00480 /** 00481 * Compute the square of the magnitude: a*a + b*b 00482 */ 00483 inline float magSqr(const float a,const float b) const; 00484 }; 00485 } 00486 00487 #endif