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

ltiHessianFunctor.h

00001 /*
00002  * Copyright (C) 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 .......: ltiHessianFunctor.h
00027  * authors ....: Peter Doerfler
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 12.3.2004
00030  * revisions ..: $Id: ltiHessianFunctor.h,v 1.7 2006/02/08 11:15:16 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_HESSIAN_FUNCTOR_H_
00034 #define _LTI_HESSIAN_FUNCTOR_H_
00035 
00036 
00037 
00038 #include "ltiImage.h"
00039 #include "ltiConvolution.h"
00040 #include "ltiTransform.h"
00041 
00042 namespace lti {
00043   /**
00044    * The hessianFunctor calculates three channels from an input channel L:
00045    *
00046    * Lxx, Lxy and Lyy which are the second derivative channels.
00047    *
00048    * The make up the Hessian of each pixel of L like this:
00049    *
00050    *          / Lxx(i,j)  Lxy(i,j) \
00051    * H(i,j)= |                      |
00052    *          \ Lxy(i,j)  Lyy(i,j) /
00053    *
00054    * See parameters::eKernelType for available kernels.
00055    *
00056    * Corresponding gradient kernels can be found in ltiGradientKernels.h
00057    */
00058   class hessianFunctor : public transform {
00059   public:
00060     /**
00061      * The parameters for the class hessianFunctor
00062      */
00063     class parameters : public transform::parameters {
00064     public:
00065 
00066       /**
00067        * Possible types of kernels for the computation of the second derivative
00068        */
00069       enum eKernelType {
00070         Ando,     /**<
00071                    * convolution of the appropriate optimal gradient kernels
00072                    * by Ando (see lti::andoKernelXX)
00073                    */
00074 
00075         Sobel,    /**
00076                    * convolution of Sobel kernels leads to 5x5
00077                    * separable kernels (see lti::sobleKernelXX):
00078                    * - XX and YY:
00079                    * /code
00080                    * [ 1  0 -2  0  1]  [ 1  4  6  4  1]
00081                    * /endcode
00082                    * - XY both:
00083                    * /code
00084                    * [ 1  2  0 -2 -1]
00085                    * /endcode
00086                    */
00087         
00088         Prewitt,  /**
00089                    * convolution of Prewitt kernels leads to 5x5
00090                    * separable kernels (see lti::prewittKernelXX):
00091                    * - XX and YY:
00092                    * /code
00093                    * [ 1  0 -2  0  1]  [ 1  2  3  2  1]
00094                    * /endcode
00095                    * - XY both:
00096                    * /code
00097                    * [ 1  1  0 -1 -1]
00098                    * /endcode
00099                    */
00100         
00101         Harris,   /**
00102                    * Harris has 1D kernels of length nine for XX and
00103                    * YY and a separable 5x5 kernel for XY (see
00104                    * lti::harrisKernelXX):
00105                    * - XX and YY:
00106                    * /code
00107                    * [ 4  4  1 -4 -10 -4  1  4  4]  []
00108                    * /endcode
00109                    * - XY both:
00110                    * /code
00111                    * [-2 -1  0  1  2]
00112                    * /endcode
00113                    */
00114 
00115         Robinson, /**
00116                    * convolution of Robinson kernels leads to 5x5
00117                    * NON-separable kernels (see lti::robinsonKernelXX):
00118                    * - XX and YY: 
00119                    * /code
00120                    * +-              -+
00121                    * |  1  2 -1 -2  1 |
00122                    * |  2 -2 -8  2  2 |
00123                    * |  3  0  0  0  3 |
00124                    * |  2 -2 -8  2  2 |
00125                    * |  1  2 -1 -2  1 |
00126                    * +-              -+
00127                    * /endcode
00128                    * - XY:        
00129                    * /code
00130                    * +-              -+
00131                    * |  1  2  1  0 -1 |
00132                    * |  2 -2 -4  0 -2 |
00133                    * |  1 -4  4  0 -1 |
00134                    * |  0  0  0  6  0 |
00135                    * | -1 -2 -1  0 -1 |
00136                    * +-              -+
00137                    * /endcode
00138                    */
00139 
00140         Kirsch,   /**
00141                    * convolution of Kirsch kernels leads to 5x5
00142                    * NON-separable kernels (see lti::kirschKernelXX):
00143                    * - XX and YY:
00144                    * /code
00145                    * +-                  -+
00146                    * |  9  18 -21 -30  25 |
00147                    * | 18  18 -51 -30  50 |
00148                    * | 27  36 -72 -60  75 |
00149                    * | 18  18 -51 -30  50 |
00150                    * |  9  18 -21 -30  25 |
00151                    * +-                  -+
00152                    * /endcode
00153                    * - XY:
00154                    * /code
00155                    * +-                   -+            
00156                    * |   9  18   3  -6 -15 |
00157                    * |  18  18 -12  -6 -30 |
00158                    * |   3 -12  -8   4  -5 |
00159                    * |  -6  -6   4  34  10 |
00160                    * | -15 -30  -5  10  25 |
00161                    * +-                   -+
00162                    * /endcode
00163                    */
00164  
00165         OGD2,     /**
00166                    * Oriented Gaussian Derivative Kernels order 2. See
00167                    * lti::ogd2Kernel for description. Remember to set
00168                    * kernelSize and kernelVariance appropriately.
00169                    */
00170 
00171         Hessian,  /**
00172                    * Kernels developed by Pablo Alvarado. See
00173                    * lti::hessianKernelXX for details.
00174                    */
00175 
00176         Classic   /**
00177                    * Classic kernels for second derivatives. Note that
00178                    * no actual kernels but a much faster manual
00179                    * implementation is used. The same is used for the
00180                    * XY direction of Hessian since the kernel is
00181                    * equal. Further, the 'same' kernels are obtained
00182                    * by convolution of lti::robertsKernelX and Y and a
00183                    * rotation of \f$\pi/4\f$. These are the kernels:
00184                    * - XX and YY are 1D:
00185                    * /code
00186                    * [1 -2  1]
00187                    * /endcode
00188                    * - XY is 3x3 separable:
00189                    * /code
00190                    * +-        -+
00191                    * |  1  0 -1 |
00192                    * |  0  0  0 |
00193                    * | -1  0  1 |
00194                    * +-        -+
00195                    * /endcode
00196                    */
00197       };
00198 
00199       /**
00200        * Default constructor
00201        */
00202       parameters();
00203 
00204       /**
00205        * Copy constructor
00206        * @param other the parameters object to be copied
00207        */
00208       parameters(const parameters& other);
00209 
00210       /**
00211        * Destructor
00212        */
00213       ~parameters();
00214 
00215       /**
00216        * Returns name of this type
00217        */
00218       const char* getTypeName() const;
00219 
00220       /**
00221        * Copy the contents of a parameters object
00222        * @param other the parameters object to be copied
00223        * @return a reference to this parameters object
00224        */
00225       parameters& copy(const parameters& other);
00226 
00227       /**
00228        * Copy the contents of a parameters object
00229        * @param other the parameters object to be copied
00230        * @return a reference to this parameters object
00231        */
00232       parameters& operator=(const parameters& other);
00233 
00234 
00235       /**
00236        * Returns a pointer to a clone of the parameters
00237        */
00238       virtual functor::parameters* clone() const;
00239 
00240       /**
00241        * Write the parameters in the given ioHandler
00242        * @param handler the ioHandler to be used
00243        * @param complete if true (the default) the enclosing begin/end will
00244        *        be also written, otherwise only the data block will be written.
00245        * @return true if write was successful
00246        */
00247       virtual bool write(ioHandler& handler,const bool complete=true) const;
00248 
00249       /**
00250        * Read the parameters from the given ioHandler
00251        * @param handler the ioHandler to be used
00252        * @param complete if true (the default) the enclosing begin/end will
00253        *        be also written, otherwise only the data block will be written.
00254        * @return true if write was successful
00255        */
00256       virtual bool read(ioHandler& handler,const bool complete=true);
00257 
00258 #     ifdef _LTI_MSC_6
00259       /**
00260        * This function is required by MSVC only, as a workaround for a
00261        * very awful bug, which exists since MSVC V.4.0, and still by
00262        * V.6.0 with all bugfixes (so called "service packs") remains
00263        * there...  This method is also public due to another bug, so please
00264        * NEVER EVER call this method directly: use read() instead
00265        */
00266       bool readMS(ioHandler& handler,const bool complete=true);
00267 
00268       /**
00269        * This function is required by MSVC only, as a workaround for a
00270        * very awful bug, which exists since MSVC V.4.0, and still by
00271        * V.6.0 with all bugfixes (so called "service packs") remains
00272        * there...  This method is also public due to another bug, so please
00273        * NEVER EVER call this method directly: use write() instead
00274        */
00275       bool writeMS(ioHandler& handler,const bool complete=true) const;
00276 #     endif
00277 
00278       // ------------------------------------------------
00279       // the parameters
00280       // ------------------------------------------------
00281 
00282       /**
00283        * Sets the kernel type used to calculate the second
00284        * derivatives. Most kernels can be found in
00285        * ltiSecondDerivativeKernels.h
00286        */
00287       eKernelType kernelType;
00288 
00289       /**
00290        * This parameter sets the size of the kernel for:
00291        * - the andoKernels (see andoKernelXX). Possible values are 5,
00292        *   7, and 9.
00293        * - ogd2Kernel, any value is possible 
00294        *
00295        * Default: 5
00296        */
00297       int kernelSize;
00298 
00299       /**
00300        * The variance for kernels that use the Gaussian. Value -1 sets
00301        * the variance appropriately for the given kernelSize. (see
00302        * e.g. ogd2Kernels)
00303        *
00304        * Default: -1
00305        */
00306       float kernelVariance;
00307 
00308     };
00309 
00310     /**
00311      * Default constructor
00312      */
00313     hessianFunctor();
00314 
00315     /**
00316      * Construct a functor using the given parameters
00317      */
00318     hessianFunctor(const parameters& par);
00319 
00320     /**
00321      * Copy constructor
00322      * @param other the object to be copied
00323      */
00324     hessianFunctor(const hessianFunctor& other);
00325 
00326     /**
00327      * Destructor
00328      */
00329     virtual ~hessianFunctor();
00330 
00331     /**
00332      * Returns the name of this type ("hessianFunctor")
00333      */
00334     virtual const char* getTypeName() const;
00335 
00336     /**
00337      * Calculated the second derivatives of the given channel which
00338      * together form the components of the Hessian matrix of each
00339      * pixel.
00340      *
00341      * @param src channel with the source data.
00342      * @param xx second derivative in xx direction.
00343      * @param xy second derivative in xy direction.
00344      * @param yy second derivative in yy direction.
00345      * @return true if apply successful or false otherwise.
00346      */
00347     bool apply(const channel& src,
00348                channel& xx, channel& xy, channel& yy) const;
00349 
00350     /**
00351      * Calculated the second derivatives of the given channel8 which
00352      * together form the components of the Hessian matrix of each
00353      * pixel. \b Note that the channel8 is converted to a channel
00354      * before calculation.
00355      *
00356      * @param src channel8 with the source data.
00357      * @param xx second derivative in xx direction.
00358      * @param xy second derivative in xy direction.
00359      * @param yy second derivative in yy direction.
00360      * @return true if apply successful or false otherwise.
00361      */
00362     bool apply(const channel8& src,
00363                channel& xx, channel& xy, channel& yy) const;
00364 
00365     /**
00366      * Copy data of "other" functor.
00367      * @param other the functor to be copied
00368      * @return a reference to this functor object
00369      */
00370     hessianFunctor& copy(const hessianFunctor& other);
00371 
00372     /**
00373      * Alias for copy member
00374      * @param other the functor to be copied
00375      * @return a reference to this functor object
00376      */
00377     hessianFunctor& operator=(const hessianFunctor& other);
00378 
00379     /**
00380      * Returns a pointer to a clone of this functor.
00381      */
00382     virtual functor* clone() const;
00383 
00384     /**
00385      * Returns used parameters
00386      */
00387     const parameters& getParameters() const;
00388 
00389     /**
00390      * Set parameters. Especially, set the correct kernels.
00391      */
00392     virtual bool updateParameters();
00393 
00394   protected:
00395 
00396     /**
00397      * Used for convolution in x or xx direction
00398      */
00399     convolution convXX;
00400 
00401     /**
00402      * Used for convolution in y or yy direction
00403      */
00404     convolution convYY;
00405 
00406     /**
00407      * Used for convolution in xy direction
00408      */
00409     convolution convXY;
00410 
00411     /**
00412      * Fast calculation of the Hessian with classic kernels [1 -2 1]
00413      * for XX and YY and [1 0 -1; 0 0 0; -1 0 1] for XY.
00414      */
00415     bool classicHessian(const channel& src,
00416                         channel& xx, channel& xy, channel& yy) const;
00417 
00418     /**
00419      * Fast computation of the second derivative in XY direction using
00420      * the kernel:
00421      * \code
00422      *  1  0 -1
00423      *  0  0  0
00424      * -1  0  1
00425      * \endcode
00426      * This is used for parameters::Hessian since it is much faster
00427      * than convolution with a very sparse kernel.
00428      */
00429     bool classicXY(const channel& src, channel& xy) const;
00430 
00431   };
00432 }
00433 
00434 #endif

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