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

ltiRegionShapeFeatures.h

00001 /*
00002  * Copyright (C) 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-Lib: Image Processing and Computer Vision Library
00026  * file .......: ltiRegionShapeFeatures.h
00027  * authors ....: Axel Berner, Pablo Alvarado, Jens Rietzschel
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 19.6.2002
00030  * revisions ..: $Id: ltiRegionShapeFeatures.h,v 1.10 2006/02/08 11:45:46 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_REGION_SHAPE_FEATURES_H_
00034 #define _LTI_REGION_SHAPE_FEATURES_H_
00035 
00036 #include "ltiGlobalFeatureExtractor.h"
00037 
00038 namespace lti {
00039   /**
00040    * This functor computes descriptors for shapes, decomposing a
00041    * \b binary mask as a sum of some basis functions.
00042    *
00043    * Several basis function sets have been implemented:
00044    *
00045    * - MPEG-7: the region shape descriptor of MPEG-7 uses the ART
00046    *   transformation, which projects the shape into the
00047    *   set \f$V_{nm}(\rho,\theta)\f$ of non-orthogonal basis functions, defined
00048    *   as
00049    *   \f$V_{nm}(\rho,\theta) = A_m(\theta) R_n(\rho)\f$, where
00050    *   \f[A_m(\theta) = \frac{1}{2\pi} \exp(jm\theta)\f]
00051    *   \f[R_n(\rho) =
00052    *      \begin{cases} 1 & n=0\\ 2\cos(\pi n \rho) & n \neq 0 \end{cases}\f]
00053    *   More information about this descriptor can be found in
00054    *   Miroslaw Bober, "MPEG-7 Visual Shape Descriptors", IEEE Transactions on
00055    *   Circuits and Systems for Video Technology, Vol. 11, No. 6, June 2001.
00056    *   or http://www.ctr.columbia.edu/~sfchang/course/vis/REF/bober-01.pdf
00057    *
00058    * - Radial Orthogonal Basis Functions:  Similar to the MPEG-7 descriptors,
00059    *   but with an orthogonal radial component:
00060    *   \f[R_n(\rho) =
00061    *      \begin{cases} 1 & n=0\\ 2\cos(2\pi n \rho) & n \neq 0 \end{cases}\f]
00062    *
00063    * - Zernike Moments:  The theory about them can be found:
00064    *   A. Khotanzad and Y.H. Hong. "Invariant Image Recognition by Zernike
00065    *   Moments".  IEEE Trans. on Pattern Analysis and Machine Intelligence,
00066    *   Vol. 12, No. 5, May 1990, pp. 489-497
00067    *
00068    * Tschebichef Moments need still to be implemented.
00069    */
00070   class regionShapeFeatures : public globalFeatureExtractor {
00071   public:
00072     /**
00073      * the parameters for the class regionShapeFeatures
00074      */
00075     class parameters : public globalFeatureExtractor::parameters {
00076     public:
00077       /**
00078        * default constructor
00079        */
00080       parameters();
00081 
00082       /**
00083        * copy constructor
00084        * @param other the parameters object to be copied
00085        */
00086       parameters(const parameters& other);
00087 
00088       /**
00089        * destructor
00090        */
00091       ~parameters();
00092 
00093       /**
00094        * returns name of this type
00095        */
00096       const char* getTypeName() const;
00097 
00098       /**
00099        * copy the contents of a parameters object
00100        * @param other the parameters object to be copied
00101        * @return a reference to this parameters object
00102        */
00103       parameters& copy(const parameters& other);
00104 
00105       /**
00106        * copy the contents of a parameters object
00107        * @param other the parameters object to be copied
00108        * @return a reference to this parameters object
00109        */
00110       parameters& operator=(const parameters& other);
00111 
00112       /**
00113        * returns a pointer to a clone of the parameters
00114        */
00115       virtual functor::parameters* clone() const;
00116 
00117       /**
00118        * write the parameters in the given ioHandler
00119        * @param handler the ioHandler to be used
00120        * @param complete if true (the default) the enclosing begin/end will
00121        *        be also written, otherwise only the data block will be written.
00122        * @return true if write was successful
00123        */
00124       virtual bool write(ioHandler& handler,const bool complete=true) const;
00125 
00126       /**
00127        * read the parameters from the given ioHandler
00128        * @param handler the ioHandler to be used
00129        * @param complete if true (the default) the enclosing begin/end will
00130        *        be also written, otherwise only the data block will be written.
00131        * @return true if write was successful
00132        */
00133       virtual bool read(ioHandler& handler,const bool complete=true);
00134 
00135 #     ifdef _LTI_MSC_6
00136       /**
00137        * this function is required by MSVC only, as a workaround for a
00138        * very awful bug, which exists since MSVC V.4.0, and still by
00139        * V.6.0 with all bugfixes (so called "service packs") remains
00140        * there...  This method is also public due to another bug, so please
00141        * NEVER EVER call this method directly: use read() instead
00142        */
00143       bool readMS(ioHandler& handler,const bool complete=true);
00144 
00145       /**
00146        * this function is required by MSVC only, as a workaround for a
00147        * very awful bug, which exists since MSVC V.4.0, and still by
00148        * V.6.0 with all bugfixes (so called "service packs") remains
00149        * there...  This method is also public due to another bug, so please
00150        * NEVER EVER call this method directly: use write() instead
00151        */
00152       bool writeMS(ioHandler& handler,const bool complete=true) const;
00153 #     endif
00154 
00155       // ------------------------------------------------
00156       // the parameters
00157       // ------------------------------------------------
00158 
00159       /**
00160        * size of the descriptor matrix.  The x component will
00161        * correspond to the number of angular frequencies to be used,
00162        * and the y component to the number of radial frequencies.
00163        *
00164        * The feature vectors will have size.x*size.y elements.
00165        *
00166        * For Zernike moments the matrix is symmetric with (size.y,size.y)
00167        *
00168        * Default value: (12 , 3)
00169        */
00170       point size;
00171 
00172       /**
00173        * In order to achieve scale invariance, the given mask will always be
00174        * first scaled to fit into square mask of the given size at one side.
00175        *
00176        * Default size: 65
00177        */
00178       int maskSize;
00179 
00180       /**
00181        * Specify if the computed coefficients should be in cartesic form
00182        * (false) (i.e. real and imaginary parts) or polar form (true)
00183        * (i.e. magnitude and phase).
00184        *
00185        * Default value: true (i.e. polar form: magnitude and phase)
00186        */
00187       bool polar;
00188 
00189       /**
00190        * Basis functions that can be used
00191        */
00192       enum basisFunctionsType {
00193         MPEG7,       /**< Use MPEG-7 non-orthogonal basis functions */
00194         OrthoRadial, /**< Similar to the region-shape descriptor of MPEG-7, but
00195                           with an orthogonal radial basis function  */
00196         Zernike      /**< use Zernike moments                       */
00197       };
00198 
00199       /**
00200        * Which basis function set should be used.
00201        *
00202        * Default:  MPEG7
00203        */
00204       basisFunctionsType basisFunctionSet;
00205     };
00206 
00207     /**
00208      * default constructor
00209      */
00210     regionShapeFeatures();
00211 
00212     /**
00213      * default constructor with parameters
00214      */
00215     regionShapeFeatures(const parameters& par);
00216 
00217     /**
00218      * copy constructor
00219      * @param other the object to be copied
00220      */
00221     regionShapeFeatures(const regionShapeFeatures& other);
00222 
00223     /**
00224      * destructor
00225      */
00226     virtual ~regionShapeFeatures();
00227 
00228     /**
00229      * returns the name of this type ("regionShapeFeatures")
00230      */
00231     virtual const char* getTypeName() const;
00232 
00233     /**
00234      * operates on the given %parameter.
00235      * @param src channel8 with the input binary mask.  All not-object pixels
00236      *            must be zero.  The object pixels must have a value 255.
00237      * @param dest channel with coefficients for the base functions.  (real
00238      *             part or magnitude, depending on parameters::polar value)
00239      * @return true if apply successful or false otherwise.
00240      */
00241     bool apply(const channel8& src,channel& dest) const;
00242 
00243     /**
00244      * operates on the given %parameter.
00245      * @param src channel8 with the input binary mask.  All not-object pixels
00246      *            must be zero.  The object pixels must have a value 255.
00247      * @param dest feature vector with coefficients for the base functions.
00248      *             (real part or magnitude, depending on
00249      *              parameters::polar value)
00250      * @return true if apply successful or false otherwise.
00251      */
00252     bool apply(const channel8& src,dvector& dest) const;
00253 
00254     /**
00255      * operates on the given %parameter.
00256      * @param src channel8 with the input binary mask.  All not-object pixels
00257      *            must be zero.  The object pixels must have a value 255.
00258      * @param dest1 channel with real part or magnitude of the coefficients,
00259      *              depending on the value of parameters::polar.
00260      * @param dest2 channel with imaginary part or phase of the coefficients,
00261      *              depending on the value of parameters::polar.
00262      * @return true if apply successful or false otherwise.
00263      */
00264     bool apply(const channel8& src,channel& dest1,channel& dest2) const;
00265 
00266     /**
00267      * operates on the given %parameter.
00268      * @param src channel8 with the input binary mask.  All not-object pixels
00269      *            must be zero.  The object pixels must have a value 255.
00270      * @param dest1 feature vector with real part or magnitude of the
00271      *              coefficients, depending on the value of parameters::polar.
00272      * @param dest2 feature vector with imaginary part or phase of the
00273      *              coefficients, depending on the value of parameters::polar.
00274      * @return true if apply successful or false otherwise.
00275      */
00276     bool apply(const channel8& src,dvector& dest1,dvector& dest2) const;
00277 
00278     /**
00279      * This method is for debugging purposes only.  It provides a tentative
00280      * reconstruction algorithm for the original shape using the given
00281      * coefficients.  Depending on the parameters::polar the output will
00282      * be in cartesic or in polar form.
00283      *
00284      * @param coef1 real part (or magnitude) of the coefficients.
00285      * @param coef2 imaginary part (or phase) of the coefficients.
00286      * @param shape1 reconstructed real part (or magnitude)
00287      * @param shape2 reconstructed imaginary part (or phase)
00288      * @return true if successful, false otherwise.
00289      */
00290     bool reconstruct(const channel& coef1,
00291                      const channel& coef2,
00292                      channel& shape1,
00293                      channel& shape2) const;
00294 
00295     /**
00296      * get one of the basis functions currently being used.
00297      * The indices must be in the valid range (specified in the parameters),
00298      * otherwise the function will return false.
00299      * @param n radial component (row)
00300      * @param m angular component (column)
00301      * @param real real part of the basis function
00302      * @param imag imaginary part of the basis function
00303      * @return true if successful, false otherwise
00304      */
00305     bool getBasisFunction(const int n, const int m,
00306                           channel& real,
00307                           channel& imag) const;
00308 
00309     /**
00310      * copy data of "other" functor.
00311      * @param other the functor to be copied
00312      * @return a reference to this functor object
00313      */
00314     regionShapeFeatures& copy(const regionShapeFeatures& other);
00315 
00316     /**
00317      * alias for copy member
00318      * @param other the functor to be copied
00319      * @return a reference to this functor object
00320      */
00321     regionShapeFeatures& operator=(const regionShapeFeatures& other);
00322 
00323     /**
00324      * returns a pointer to a clone of this functor.
00325      */
00326     virtual functor* clone() const;
00327 
00328     /**
00329      * set functor's parameters.
00330      * This member makes a copy of <em>theParam</em>: the functor
00331      * will keep its own copy of the parameters!
00332      * @return true if successful, false otherwise
00333      */
00334     virtual bool updateParameters();
00335 
00336     /**
00337      * returns used parameters
00338      */
00339     const parameters& getParameters() const;
00340 
00341   protected:
00342     /**
00343      * dot product between two matrices of the same size
00344      */
00345     void dot(const channel& reA, const channel& imA,
00346              const channel& reB, const channel& imB,
00347              float& real,float& imag) const;
00348 
00349     /**
00350      * calculates the look up tables (LUT) for the transformation
00351      * (suitable to the given parameters::maskSize)
00352      * @return true if successful
00353      */
00354     bool calcLUT();
00355 
00356     /**
00357      * Test the orthogonality of the base functions
00358      * The comparition matrix will be a square matrix with the size.x*sizey
00359      * elements at one size.
00360      */
00361     bool testOrthogonality(channel& ortho) const;
00362 
00363     /**
00364      * crop the object in the mask and resizes it to the parameters::maskSize
00365      * (here: the center of mass of the object is
00366      *        in the center of the new image)
00367      */
00368     void resizeMask(const channel8& src,
00369         channel& ssrc) const;
00370 
00371     /**
00372      * real part of the basis functions (LUT)
00373      */
00374     std::vector< std::vector<channel> > lutR;
00375 
00376     /**
00377      * imaginary part of the basis functions (LUT)
00378      */
00379     std::vector< std::vector<channel> > lutI;
00380 
00381     /**
00382      * radius matrix.  It will contain the distance of a pixel to the
00383      * center of the image:
00384      * f(x,y) = radius ; radius = ((x-xcenter)^2+(y-ycenter)^2)^0.5
00385      */
00386     channel radLut;
00387 
00388     /**
00389      * static function used to binarize a channel.
00390      * All values under 0.5 will be set to 0 and all values above 0.5 will
00391      * be set to 1.0
00392      */
00393     static float binarize(const float& x);
00394 
00395     /**
00396      * flag to remember the last basis function set
00397      */
00398     parameters::basisFunctionsType lastBasisFunctionSet;
00399 
00400 
00401     /**
00402      * used to decide whether zernike moment (n,m) exists
00403      */
00404     std::vector<std::vector<bool> > vecNM;
00405 
00406     /**
00407      * compute factorial of arg
00408      */
00409     double fac(int arg);
00410 
00411   };
00412 }
00413 
00414 #endif

Generated on Sat Apr 10 15:26:04 2010 for LTI-Lib by Doxygen 1.6.1