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 .......: ltiGradientFunctor.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 1.6.2003 00030 * revisions ..: $Id: ltiGradientFunctor.h,v 1.10 2006/02/08 11:12:47 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_GRADIENT_FUNCTOR_H_ 00034 #define _LTI_GRADIENT_FUNCTOR_H_ 00035 00036 #include "ltiTransform.h" 00037 #include "ltiArctanLUT.h" 00038 00039 namespace lti { 00040 /** 00041 * The gradient is a simple wrapper for the convolution functor with 00042 * some convenience parameterization to choose between different common 00043 * gradient kernels. 00044 * 00045 * Not only the classical simple difference computation (right minus 00046 * left for the x direction or bottom minus top for the y direction) 00047 * and the classical Sobel, Prewitt, Robinson, Roberts and Kirsch 00048 * kernels can be used, but the more sophisticated Ando optimal 00049 * kernels (see lti::gradientKernelX) and the approximation using 00050 * oriented gaussian derivatives can be used. 00051 * 00052 * The kernel computes the gradient for lti::channel %objects only. For 00053 * color images you can use one of the derived classes. 00054 * 00055 * @see lti::gradientFunctor,lti::gradientKernelX,lti::colorContrastGradient 00056 * 00057 * @ingroup gLinearFilters 00058 */ 00059 class gradientFunctor : public transform { 00060 public: 00061 /** 00062 * the parameters for the class gradientFunctor 00063 */ 00064 class parameters : public transform::parameters { 00065 public: 00066 /** 00067 * default constructor 00068 */ 00069 parameters(); 00070 00071 /** 00072 * copy constructor 00073 * @param other the parameters object to be copied 00074 */ 00075 parameters(const parameters& other); 00076 00077 /** 00078 * destructor 00079 */ 00080 ~parameters(); 00081 00082 /** 00083 * returns name of this type 00084 */ 00085 const char* getTypeName() const; 00086 00087 /** 00088 * copy the contents of a parameters object 00089 * @param other the parameters object to be copied 00090 * @return a reference to this parameters object 00091 */ 00092 parameters& copy(const parameters& other); 00093 00094 /** 00095 * copy the contents of a parameters object 00096 * @param other the parameters object to be copied 00097 * @return a reference to this parameters object 00098 */ 00099 parameters& operator=(const parameters& other); 00100 00101 00102 /** 00103 * returns a pointer to a clone of the parameters 00104 */ 00105 virtual functor::parameters* clone() const; 00106 00107 /** 00108 * write the parameters in the given ioHandler 00109 * @param handler the ioHandler to be used 00110 * @param complete if true (the default) the enclosing begin/end will 00111 * be also written, otherwise only the data block will be written. 00112 * @return true if write was successful 00113 */ 00114 virtual bool write(ioHandler& handler,const bool complete=true) const; 00115 00116 /** 00117 * read the parameters from the given ioHandler 00118 * @param handler the ioHandler to be used 00119 * @param complete if true (the default) the enclosing begin/end will 00120 * be also written, otherwise only the data block will be written. 00121 * @return true if write was successful 00122 */ 00123 virtual bool read(ioHandler& handler,const bool complete=true); 00124 00125 # ifdef _LTI_MSC_6 00126 /** 00127 * this function is required by MSVC only, as a workaround for a 00128 * very awful bug, which exists since MSVC V.4.0, and still by 00129 * V.6.0 with all bugfixes (so called "service packs") remains 00130 * there... This method is also public due to another bug, so please 00131 * NEVER EVER call this method directly: use read() instead 00132 */ 00133 bool readMS(ioHandler& handler,const bool complete=true); 00134 00135 /** 00136 * this function is required by MSVC only, as a workaround for a 00137 * very awful bug, which exists since MSVC V.4.0, and still by 00138 * V.6.0 with all bugfixes (so called "service packs") remains 00139 * there... This method is also public due to another bug, so please 00140 * NEVER EVER call this method directly: use write() instead 00141 */ 00142 bool writeMS(ioHandler& handler,const bool complete=true) const; 00143 # endif 00144 00145 // ------------------------------------------------ 00146 // the parameters 00147 // ------------------------------------------------ 00148 00149 /** 00150 * Format types 00151 */ 00152 enum eOutputFormat { 00153 Polar, /**< Polar coordinates first magnitud, then angle */ 00154 Cartesic, /**< Cartesian coordinates first x, then y */ 00155 }; 00156 00157 /** 00158 * The output of the apply methods can be in polar or cartesic 00159 * coordinates. You can specify here which format you prefer. 00160 * 00161 * Default value: Polar 00162 */ 00163 eOutputFormat format; 00164 00165 00166 /** 00167 * Kernel Type 00168 */ 00169 enum eKernelType { 00170 Optimal, /**< Use the optimal kernel gradients of Ando 00171 * (see lti::gradientKernelX). 00172 */ 00173 OGD, /**< Use oriented Gaussian derivatives 00174 * 00175 */ 00176 Difference, /**< 00177 * Simplest (and fastest) kernel just right-left, 00178 * top-bottom 00179 */ 00180 Roberts, /**< 00181 * Also very simple, but has a location-bias of half pixel. 00182 * These are 2x2 kernels, 00183 */ 00184 Sobel, /**< 00185 * 3x3 separable kernel with a 1 2 1, -1 0 1 sub-kernels 00186 * (see lti::sobelKernelX) 00187 */ 00188 Prewitt, /**< 00189 * 3x3 separable kernel with a 1 1 1, -1 0 1 sub-kernels 00190 * (see lti::prewittKernelX) 00191 */ 00192 Robinson, /** 00193 * 3x3 non-separable kernel (see lti::robinsonKernelX) 00194 */ 00195 Kirsch, /** 00196 * 3x3 non-separable kernel (see lti::kirschKernelX) 00197 */ 00198 Harris /**< 00199 * 1x5 separable kernel -2 -1 0 1 2 00200 * (see lti::harrisKernelX) 00201 */ 00202 }; 00203 00204 /** 00205 * Type of gradient kernel to be used. 00206 * 00207 * Default value: Optimal 00208 */ 00209 eKernelType kernelType; 00210 00211 /** 00212 * Size of the kernel used. 00213 * 00214 * This attribute is used only for the Optimal and OGD Kernel types. 00215 * 00216 * For the Optimal kernel type, the value \b must be 3, 4, or 5. 00217 * For the OGD odd values greater or equal 3 should be used. 00218 * 00219 * Default value: 3 00220 */ 00221 int gradientKernelSize; 00222 00223 /** 00224 * Variance used for the Gaussian. 00225 * 00226 * This argument has effect only if kernelType is OGD. 00227 * 00228 * It is the variance use for the Gaussian to be derived as approximation 00229 * for a gradient kernel. 00230 * 00231 * Default value: -1 (i.e. the variance will be computed from the size 00232 * of the kernel (\a gradientKernelSize) ) 00233 */ 00234 float ogdVariance; 00235 }; 00236 00237 /** 00238 * Default constructor 00239 */ 00240 gradientFunctor(const bool initializeParameters = true); 00241 00242 /** 00243 * Construct a functor using gradient kernels with the specified values. 00244 * 00245 * @param format specify the format to be use: Cartesic or Polar 00246 * @param gradKernelSize size for the gradient kernel to be used. 00247 */ 00248 gradientFunctor(const parameters::eOutputFormat& format, 00249 const int gradKernelSize=0); 00250 00251 /** 00252 * Construct a functor using the given parameters 00253 */ 00254 gradientFunctor(const parameters& par); 00255 00256 /** 00257 * copy constructor 00258 * @param other the object to be copied 00259 */ 00260 gradientFunctor(const gradientFunctor& other); 00261 00262 /** 00263 * destructor 00264 */ 00265 virtual ~gradientFunctor(); 00266 00267 /** 00268 * returns the name of this type ("gradientFunctor") 00269 */ 00270 virtual const char* getTypeName() const; 00271 00272 /** 00273 * Computes the 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 channel& src, 00283 channel& xOrMag, 00284 channel& yOrArg) const; 00285 00286 /** 00287 * Computes the gradient magnitude of the given channel. 00288 * 00289 * @param src channel with the source data. 00290 * @param mag the resulting magnitude of the gradient will be left here. 00291 * 00292 * @return true if apply successful or false otherwise. 00293 */ 00294 bool apply(const channel& src, 00295 channel& mag) const; 00296 00297 /** 00298 * Computes the gradient magnitude of the given channel. 00299 * 00300 * @param srcdest channel with source data, the resulting magnitude 00301 * will be left here too. 00302 * 00303 * @return true if apply successful or false otherwise. 00304 */ 00305 bool apply(channel& srcdest) const; 00306 00307 00308 /** 00309 * Computes the gradient of the given channel. 00310 * 00311 * @param src channel8 with the source data. 00312 * @param xOrMag the resulting x component or magnitude of the gradient 00313 * will be left here. 00314 * @param yOrArg the resulting y component or argument (orientation) of 00315 * the gradient will be left here. 00316 * @return true if apply successful or false otherwise. 00317 */ 00318 bool apply(const channel8& src, 00319 channel& xOrMag, 00320 channel& yOrArg) const; 00321 00322 /** 00323 * copy data of "other" functor. 00324 * @param other the functor to be copied 00325 * @return a reference to this functor object 00326 */ 00327 gradientFunctor& copy(const gradientFunctor& other); 00328 00329 /** 00330 * alias for copy member 00331 * @param other the functor to be copied 00332 * @return a reference to this functor object 00333 */ 00334 gradientFunctor& operator=(const gradientFunctor& other); 00335 00336 /** 00337 * returns a pointer to a clone of this functor. 00338 */ 00339 virtual functor* clone() const; 00340 00341 /** 00342 * returns used parameters 00343 */ 00344 const parameters& getParameters() const; 00345 00346 protected: 00347 /** 00348 * @name One channel gradient computation 00349 */ 00350 //@{ 00351 /** 00352 * compute the gradient of the src channel8 using the adecuate 00353 * method xyDifferentiateXYZ 00354 */ 00355 bool computeGradientCart(const channel& src, 00356 channel& dx, 00357 channel& dy) const; 00358 00359 /** 00360 * differentiate the image in X and Y directions using operator (-1 0 1) 00361 * @param src source channel 00362 * @param dx x component of the gradient 00363 * @param dy y component of the gradient 00364 * @return true if successful, false otherwise 00365 */ 00366 bool xyDifferentiateImageCart(const channel& src, 00367 channel& dx, 00368 channel& dy) const; 00369 00370 /** 00371 * differentiate the image in X and Y directions using optimal operators. 00372 * @param src source channel 00373 * @param dx x component of the gradient 00374 * @param dy y component of the gradient 00375 * @return true if successful, false otherwise 00376 */ 00377 bool xyDifferentiateImageCartOpt(const channel& src, 00378 channel& dx, 00379 channel& dy) const; 00380 00381 /** 00382 * differentiate the image in X and Y directions using optimal operators. 00383 * @param src source channel 00384 * @param dx x component of the gradient 00385 * @param dy y component of the gradient 00386 * @return true if successful, false otherwise 00387 */ 00388 bool xyDifferentiateImageCartClassicSep(const channel& src, 00389 channel& dx, 00390 channel& dy) const; 00391 00392 /** 00393 * differentiate the image in X and Y directions using classic gradients. 00394 * @param src source channel 00395 * @param dx x component of the gradient 00396 * @param dy y component of the gradient 00397 * @return true if successful, false otherwise 00398 */ 00399 bool xyDifferentiateImageCartClassic2D(const channel& src, 00400 channel& dx, 00401 channel& dy) const; 00402 00403 /** 00404 * Roberts operator 00405 * 00406 * calculates the gradient at the center of a 2x2 mask. The position marked 00407 * with "S" is the position where the gradient is stored at in the output 00408 * channels: 00409 * 00410 * \code 00411 * ( S +) 00412 * ( + +) 00413 * \endcode 00414 * 00415 * (The origin (0,0) is at the bottom left of the image) 00416 * @param src the already smoothed image 00417 * @param dx x component of the gradient 00418 * @param dy y component of the gradient 00419 * @return returns NULL if successful, a textual error message otherwise 00420 */ 00421 bool xyDifferentiateImageCartInterPixel(const channel& src, 00422 channel& dx, 00423 channel& dy) const; 00424 00425 /** 00426 * Differentiate the image in X and Y directions using operator (-1 0 1) 00427 * The result will be directly in polar coordinates 00428 * @param src source channel 00429 * @param gradAbs magnitude of the gradient. 00430 * @param gradPhi argument of the gradient (angle). 00431 * @return true if successful, false otherwise 00432 */ 00433 bool xyDifferentiateImage(const channel8& src, 00434 channel& gradAbs, 00435 channel& gradPhi) const; 00436 00437 //@} 00438 00439 /** 00440 * Look-Up Table for computation of arc tangent 00441 */ 00442 arctanLUT atan2; 00443 00444 /** 00445 * convert a pair of values in cartesic system into a pair in 00446 * polar system 00447 * 00448 * The LUT takes care that the returned value lies between 0 and 2*Pi 00449 */ 00450 inline void cartToPolar(const int dx,const int dy, 00451 float& mag,float& angle) const; 00452 00453 }; 00454 } 00455 00456 #endif