LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiGradientFunctor.h

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

Generated on Sat Apr 10 15:25:36 2010 for LTI-Lib by Doxygen 1.6.1