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

ltiScaleSpacePyramid.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 .......: ltiScaleSpacePyramid.h
00027  * authors ....: Pablo Alvarado, Frederik Lange
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 17.03.2003
00030  * revisions ..: $Id: ltiScaleSpacePyramid.h,v 1.6 2006/02/08 11:47:36 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_SCALESPACE_PYRAMID_H_
00034 #define _LTI_SCALESPACE_PYRAMID_H_
00035 
00036 #include "ltiObject.h"
00037 #include "ltiFunctor.h"
00038 #include "ltiPyramid.h"
00039 
00040 #include "ltiInterpolatorType.h"
00041 #include "ltiNearestNeighborInterpolator.h"
00042 #include "ltiBilinearInterpolator.h"
00043 #include "ltiBiquadraticInterpolator.h"
00044 
00045 #include "ltiMath.h"
00046 
00047 namespace lti {
00048 
00049   /**
00050    * Image pyramid to represent the scale space.
00051    *
00052    * This pyramid can be used for scale-dependent image access.  At
00053    * construction time the input channel is downsampled to several
00054    * scales as specified with the resize()-method.
00055    *
00056    * Each channel is downsampled by "factor"-parameter with Gaussian
00057    * convolution applied.  This factor is usually greater than 0.5 (the
00058    * usual one in image pyramids), but still must be less than 1.0.
00059    * This is done to archieve a much higher precision.
00060    *
00061    * As with other pyramids, the template type T represents the image type.
00062    * Usually you will want to use an scaleSpacePyramid<channel>.
00063    *
00064    * For this class the term "level" denotes one of the existent layers of
00065    * the pyramid.  The term "scale" denotes a real value.  The "levels"
00066    * have explicit scales, that can be obtaind with getLevelScale().
00067    *  
00068    */
00069   template<class T> 
00070   class scaleSpacePyramid : public pyramid<T> {
00071   public:
00072     /**
00073      * Type of elements of the channels of type T
00074      */
00075     typedef typename T::value_type value_type;
00076       
00077     /**
00078      * Parameters for the generation of scaleSpace pyramids.
00079      *
00080      * Even if scaleSpacePyramid is by no means a functor, the
00081      * number of parameters required in its generation is large enough to 
00082      * justify the use of a parameters class.  It is just inherited from
00083      * functor::parameters to reuse the interface defined there.
00084      */
00085     class parameters : public functor::parameters {
00086     public:
00087       /**
00088        * default constructor
00089        */
00090       parameters() : functor::parameters() {        
00091         automaticKernel = bool(true);
00092         kernelSize = int(5);
00093         kernelVariance = double(1.6*1.6);
00094         gaussian = bool(false);
00095         factor = double(0.793700526); // (0.5^(1/3))
00096         interpolatorType = BilinearInterpolator;
00097       };
00098 
00099       /**
00100        * copy constructor
00101        * @param other the parameters object to be copied
00102        */
00103       parameters(const parameters& other) : functor::parameters() {
00104         copy(other);
00105       }
00106       
00107       /**
00108        * destructor
00109        */
00110       ~parameters() {
00111       };
00112 
00113       /**
00114        * returns name of this type
00115        */
00116       const char* getTypeName() const {
00117         return "scaleSpacePyramid::parameters";
00118       };
00119 
00120       /**
00121        * copy the contents of a parameters object
00122        * @param other the parameters object to be copied
00123        * @return a reference to this parameters object
00124        */
00125       parameters& copy(const parameters& other) {
00126 #     ifndef _LTI_MSC_6
00127         // MS Visual C++ 6 is not able to compile this...
00128         functor::parameters::copy(other);
00129 #     else
00130         // ...so we have to use this workaround.
00131         // Conditional on that, copy may not be virtual.
00132         functor::parameters& (functor::parameters::* p_copy)
00133                             (const functor::parameters&) =
00134                             functor::parameters::copy;
00135         (this->*p_copy)(other);
00136 #     endif
00137 
00138         
00139         automaticKernel = other.automaticKernel;
00140         kernelSize = other.kernelSize;
00141         kernelVariance = other.kernelVariance;
00142         gaussian = other.gaussian;
00143         factor = other.factor;
00144         interpolatorType = other.interpolatorType;
00145 
00146         return *this;
00147       };
00148 
00149       /**
00150        * copy the contents of a parameters object
00151        * @param other the parameters object to be copied
00152        * @return a reference to this parameters object
00153        */
00154       parameters& operator=(const parameters& other) {
00155         return copy(other);
00156       };
00157 
00158       /**
00159        * returns a pointer to a clone of the parameters
00160        */
00161       virtual functor::parameters* clone() const {
00162         return new parameters(*this);
00163       };
00164 
00165 #     ifndef _LTI_MSC_6
00166       /**
00167        * write the parameters in the given ioHandler
00168        * @param handler the ioHandler to be used
00169        * @param complete if true (the default) the enclosing begin/end will
00170        *        be also written, otherwise only the data block will be written.
00171        * @return true if write was successful
00172        */
00173       virtual bool write(ioHandler& handler,const bool complete=true) const
00174 #     else
00175       /**
00176        * this function is required by MSVC only, as a workaround for a
00177        * very awful bug, which exists since MSVC V.4.0, and still by
00178        * V.6.0 with all bugfixes (so called "service packs") remains
00179        * there...  This method is also public due to another bug, so please
00180        * NEVER EVER call this method directly: use write() instead
00181        */
00182       bool writeMS(ioHandler& handler,const bool complete=true) const
00183 #     endif
00184       {
00185         bool b = true;
00186         if (complete) {
00187           b = handler.writeBegin();
00188         }
00189         
00190         if (b) {          
00191           lti::write(handler,"factor",factor);
00192           lti::write(handler,"interpolatorType",interpolatorType);
00193           lti::write(handler,"gaussian",gaussian);
00194           lti::write(handler,"automaticKernel",automaticKernel);
00195           lti::write(handler,"kernelSize",kernelSize);
00196           lti::write(handler,"kernelVariance",kernelVariance);
00197         }
00198 
00199 #     ifndef _LTI_MSC_6
00200         // This is the standard C++ code, which MS Visual C++ 6 is not able to
00201         // compile...
00202         b = b && functor::parameters::write(handler,false);
00203 #     else
00204         bool (functor::parameters::* p_writeMS)(ioHandler&,
00205                                                          const bool) const =
00206           functor::parameters::writeMS;
00207         b = b && (this->*p_writeMS)(handler,false);
00208 #     endif
00209 
00210         if (complete) {
00211           b = b && handler.writeEnd();
00212         }
00213 
00214         return b;
00215       }
00216 
00217 #     ifdef _LTI_MSC_6
00218       /**
00219        * write the parameters in the given ioHandler
00220        * @param handler the ioHandler to be used
00221        * @param complete if true (the default) the enclosing begin/end will
00222        *        be also written, otherwise only the data block will be written.
00223        * @return true if write was successful
00224        */
00225       bool write(ioHandler& handler,
00226                  const bool complete=true) const {
00227         // ...we need this workaround to cope with another really
00228         // awful MSVC bug.
00229         return writeMS(handler,complete);
00230       }
00231 #     endif
00232 
00233 
00234 #     ifndef _LTI_MSC_6
00235       /**
00236        * read the parameters from the given ioHandler
00237        * @param handler the ioHandler to be used
00238        * @param complete if true (the default) the enclosing begin/end will
00239        *        be also written, otherwise only the data block will be written.
00240        * @return true if write was successful
00241        */
00242       virtual bool read(ioHandler& handler,const bool complete=true)
00243 #     else
00244       /**
00245        * this function is required by MSVC only, as a workaround for a
00246        * very awful bug, which exists since MSVC V.4.0, and still by
00247        * V.6.0 with all bugfixes (so called "service packs") remains
00248        * there...  This method is also public due to another bug, so please
00249        * NEVER EVER call this method directly: use read() instead
00250        */
00251       bool readMS(ioHandler& handler,const bool complete=true)
00252 #     endif
00253       {
00254         bool b = true;
00255         if (complete) {
00256           b = handler.readBegin();
00257         }
00258         
00259         if (b) {          
00260           b = lti::read(handler,"factor",factor) && b;
00261           b = lti::read(handler,"interpolatorType",interpolatorType) && b;
00262           b = lti::read(handler,"gaussian",gaussian) && b;
00263           b = lti::read(handler,"automaticKernel",automaticKernel) && b;
00264           b = lti::read(handler,"kernelSize",kernelSize) && b;
00265           b = lti::read(handler,"kernelVariance",kernelVariance) && b;
00266         }
00267 
00268 #       ifndef _LTI_MSC_6
00269         // This is the standard C++ code, which MS Visual C++ 6 is not
00270         // able to compile...
00271         b = b && functor::parameters::read(handler,false);
00272 #       else
00273         bool (functor::parameters::* p_readMS)(ioHandler&,
00274                                                         const bool) =
00275           functor::parameters::readMS;
00276         b = b && (this->*p_readMS)(handler,false);
00277 #       endif
00278 
00279         if (complete) {
00280           b = b && handler.readEnd();
00281         }
00282         
00283         return b;
00284       }
00285 
00286 #     ifdef _LTI_MSC_6
00287       /**
00288        * read the parameters from the given ioHandler
00289        * @param handler the ioHandler to be used
00290        * @param complete if true (the default) the enclosing begin/end will
00291        *        be also written, otherwise only the data block will be written.
00292        * @return true if write was successful
00293        */
00294       bool read(ioHandler& handler,const bool complete=true) {
00295         // ...we need this workaround to cope with another really awful MSVC
00296         // bug.
00297         return readMS(handler,complete);
00298       }
00299 #     endif
00300 
00301       // ------------------------------------------------
00302       // the parameters
00303       // ------------------------------------------------
00304 
00305       /**
00306        * Specify if each level in the pyramid should be smoothed with a
00307        * Gaussian kernel or not.
00308        *
00309        * Default: false
00310        */
00311       bool gaussian;
00312       
00313       /**
00314        * Kernel size used to smooth each pyramid level. 
00315        *
00316        * Used only if the automaticKernel mode is set to false and 
00317        * Gaussian smoothing is desired.
00318        *
00319        * Default is 5
00320        */
00321       int kernelSize;
00322       
00323       /**
00324        * Kernel variance
00325        *
00326        * Used only if the automaticKernel mode is set to false and  
00327        * Gaussian smoothing is desired.
00328        *
00329        * Default value: 1.6*1.6
00330        */
00331       double kernelVariance;
00332 
00333       /**
00334        * Automatic kernel computation.
00335        *
00336        * The size and the variance of the smoothing kernel are determined
00337        * depending on the factor for downsampling.
00338        *
00339        * Default value: true
00340        */
00341       bool automaticKernel;
00342 
00343       /**
00344        * Scale factor between adjacent pyramid layers. 
00345        *
00346        * This parameter determines the factor between the resolution
00347        * resolution(n) = resolution(0) * factor^n
00348        *
00349        * This value should be in the interval ]0.5,1.0[ in order for many
00350        * of the interpolation methods to work properly.
00351        *
00352        * Default: cubic root of 0.5 == 0.793700526
00353        */
00354       double factor;
00355 
00356       /**
00357        * Interpolation mode used.
00358        *
00359        * The "downsampling" will use interpolation to get values between the
00360        * pixels of a higher resolution level.
00361        *
00362        * Default: BilinearInterpolator
00363        */
00364       eInterpolatorType interpolatorType;
00365     };
00366 
00367     /**
00368      * Default constructor
00369      */
00370     scaleSpacePyramid<T>();
00371 
00372     /**
00373      * Create a pyramid with the given number of levels and the given
00374      * parameters
00375      */
00376     scaleSpacePyramid<T>(const int levels,
00377                          const parameters& par = parameters());
00378 
00379     /**
00380      * Copy constructor
00381      *
00382      * @param other the object to be copied
00383      */
00384     scaleSpacePyramid<T>(const scaleSpacePyramid<T>& other);
00385 
00386     /**
00387      * Destructor
00388      */
00389     virtual ~scaleSpacePyramid<T>();
00390 
00391     /**
00392      * Returns the name of this type ("scaleSpacePyramid<T>")
00393      */
00394     virtual const char* getTypeName() const;
00395         
00396     /**
00397      * Copy data of "other" functor.
00398      *
00399      * @param other the functor to be copied
00400      * @return a reference to this functor object
00401      */
00402     scaleSpacePyramid<T>& copy(const scaleSpacePyramid<T>& other);
00403 
00404     /**
00405      * Alias for copy member
00406      *
00407      * @param other the functor to be copied
00408      * @return a reference to this functor object
00409      */
00410     scaleSpacePyramid<T>& operator=(const scaleSpacePyramid<T>& other);
00411 
00412     /**
00413      * Returns a pointer to a clone of this pyramid.
00414      */
00415     virtual mathObject* clone() const;
00416 
00417     /**
00418      * Change the number of resolutions of the pyramid
00419      *
00420      * @param levels the new number of levels or layers of the pyramid
00421      * @param copyData if true (default), the old data will be keeped.
00422      *                 If false, all data will be lost.
00423      */
00424     void resize(const int& levels,
00425                 const bool& copyData=true);
00426     
00427     /**
00428      * set parameters
00429      */
00430     virtual bool setParameters(const parameters& par);
00431 
00432     /**
00433      * Get a read-only reference to parameters.
00434      */
00435     const parameters&  getParameters() const;
00436 
00437     /**
00438      * Generate the pyramid of the given object.
00439      *
00440      * The pyramid will contain the number of levels specified in
00441      * the construction or in the resize() method. 
00442      *
00443      * The level "0" will correspond to the original channel or
00444      * image.  The level \e i+1 is always a parameters::factor
00445      * times smaller than the level \e i at each axis.
00446      */
00447     void generate(const T& src);
00448     
00449     /**
00450      * Generate the pyramid of the given object.
00451      *
00452      * The pyramid will contain the number of resolutions specified 
00453      * by \a theResolutions.
00454      *
00455      * The level "0" will correspond to the original channel or
00456      * image.  The resolution \e i+1 is always a parameters::factor
00457      * times smaller than the level \e i at each axis.
00458      */
00459     void generate(const T& src,const int& numLevels);
00460 
00461     /**
00462      * @name Scale-space access operators
00463      *
00464      * The scale space can be accessed at any real x,y and scale values.
00465      * Interpolation is necessary to get a spatial subpixel or a value
00466      * between scales.  The methods can use several one-dimensional
00467      * interpolations, which is relative fast to compute, or can use
00468      * more precise but much expensive two or three dimensional
00469      * interpolation polynoms.
00470      *
00471      * The spatial coordinates are always given with respect to the first
00472      * level (level 0), which mean they must be between (0,0) and 
00473      * (at(0).lastColumn(),at(0).lastRow()).
00474      */
00475     //@{
00476     
00477     /**
00478      * Get an "in level" nearest neighbor interpolation.
00479      *
00480      * The given level \a lev must be in the pyramid.
00481      */
00482     value_type nearestAt(const float y,const float x,const int lev) const;
00483 
00484     /**
00485      * Get an "in level" bilinear interpolation.
00486      *
00487      * The given level \a lev must be in the pyramid.
00488      */
00489     value_type bilinearAt(const float y,const float x,const int lev) const;
00490  
00491     /**
00492      * Get an "in level" biquadratic interpolation.
00493      *
00494      * The given level \a lev must be in the pyramid.
00495      */
00496     value_type biquadraticAt(const float y,const float x,const int lev) const;
00497 
00498     /**
00499      * Get an "in level" quadratic interpolation.
00500      *
00501      * The given level \a lev must be in the pyramid.  
00502      *
00503      * Since the pixel (x,y) at level \a lev has eight neighbors and the
00504      * quadratic function only six coefficients, the least square error
00505      * quadratic surface passing exactly through the middle point will be
00506      * computed, i.e. five of the six coefficients will be determined using
00507      * the eight neighbor points of the middle one.
00508      *
00509      * Please note that there is an overload of this function for a
00510      * scale value \a s instead of a level, which does a similar task but also
00511      * interpolates between levels (see
00512      * quadraticAt(const float,const float,const float)).
00513      */
00514     value_type quadraticAt(const float y,const float x,const int lev) const;
00515 
00516     /**
00517      * Get a "between-scales" trilinear interpolation.
00518      *
00519      * The given scale \a s must be in the pyramid,
00520      * i.e. s>=0 and s<=parameters::factor^size()-1
00521      */
00522     value_type trilinearAt(const float y,const float x,const float s) const;
00523  
00524     /**
00525      * Get an "between-scales" triquadratic interpolation
00526      *
00527      * The given scale \a s must be in the pyramid,
00528      * i.e. s>=0 and s<=parameters::factor^size()-1
00529      */
00530     value_type triquadraticAt(const float y,const float x,const float s) const;
00531 
00532     /**
00533      * Compute for the given (x,y) spatial coordinates three "in-level"
00534      * quadratic interpolations at the three nearest levels of the given
00535      * scale \a s, and from the three new values interpolate
00536      * quadratically for the corresponding scale value.
00537      *
00538      * The given scale \a s must be in the pyramid,
00539      * i.e. s>=0 and s<=parameters::factor^(size()-1)  
00540      *
00541      * This is therefore a combination between 2D and 1D quadratic
00542      * interpolations.
00543      *
00544      * Note that if the scale \a s is integer it is faster to call the other
00545      * quadraticAt method that expects the level of the pyramid.
00546      *
00547      * @see quadraticAt(const float,const float,const int) const;
00548      */
00549     value_type quadraticAt(const float y,const float x,const float s) const;
00550     //@}
00551 
00552     /**
00553      * Get the scale corresponding for a circular area of the given
00554      * radius.  
00555      *
00556      * At the scale 0, the radius of a pixel is 0.5.
00557      */
00558     float getScaleForRadius(const float radius) const;
00559 
00560     /**
00561      * Get the radius of one "pixel" for the given level.
00562      *
00563      * At the level 0, the radius of a pixel is 0.5.
00564      */
00565     float getRadiusForScale(const float scale) const;
00566 
00567     /**
00568      * Return the scale for the levels of the pyramid
00569      */
00570     inline const double& getLevelScale(const int level) const;
00571 
00572     /**
00573      * Type of extrema detected at a given point
00574      */
00575     enum eExtremaType {
00576       NoExtremum=0, /**< No extremum point has been detected */
00577       Minimum,      /**< A (local) minimum has been detected */
00578       Maximum,      /**< A (local) maximum has been detected */
00579     };
00580 
00581     /**
00582      * Seaches for an extremum with sub-pixel accuracy in a 3x3 region
00583      * around the given access point.
00584      *
00585      * A 2D quadratic function will be used to compute the sub-pixel values.
00586      *
00587      * Note that it only makes sense to call this method if the
00588      * (col,row) point of the given level is already a extremum or a
00589      * minimum in the discrete coordinates system, i.e. if the point
00590      * is greater (smaller)  than its eight neighbors.  Otherwise this method
00591      * will just return "NoExtremum".
00592      *
00593      * @param row row in coordinates of the given level, i.e. this value must
00594      *            be between 0 and at(level).rows()
00595      * @param col column in coordinates of the given level, i.e. this value
00596      *            must be between 0 and at(level).columns()
00597      * @param level level at which the extremum must be looked for.
00598      * @param spRow in case a extremum is found in the 3x3 region, this is the
00599      *              row of the found extremum using the coordinates of the 
00600      *              corresponding level. 
00601      * @param spCol in case a extremum is found in the 3x3 region, this is the
00602      *              column of the found extremum using the coordinates of the 
00603      *              corresponding level.
00604      *
00605      * @return the type of extremum detected.  In case a
00606      *         maximum/minimum was found, the spRow and spCol will contain the
00607      *         position with sub-pixel precision of the found extremum.
00608      */
00609     eExtremaType interpolateExtremum(const int row, 
00610                                      const int col,
00611                                      const int level,
00612                                      float& spRow,
00613                                      float& spCol) const;
00614 
00615 
00616     /**
00617      * Seaches for an extremum with sub-pixel accuracy in a 3x3x3 region
00618      * around the given access point.
00619      *
00620      * A 3D quadratic function will be used to compute the sub-pixel values.
00621      *
00622      * This function will only work if the parameters::factor is in ]0.5,1.0[.
00623      *
00624      * Note that in makes only sense to call this method if the (col,row)
00625      * point of the given level is already a extremum in the discrete
00626      * coordinates system, i.e. if the point is greater than its 26
00627      * neighbors.  Otherwise this method will just return "NoExtremum".
00628      *
00629      * @param row row in coordinates of the given level, i.e. this value must
00630      *            be between 0 and at(level).rows()
00631      * @param col column in coordinates of the given level, i.e. this value
00632      *            must be between 0 and at(level).columns()
00633      * @param level level at which the extremum must be looked for.
00634      * @param spRow in case an extremum is found in the 3x3x3 region, this is 
00635      *              the row of the found extremum using the coordinates of 
00636      *              the corresponding level. 
00637      * @param spCol in case an extremum is found in the 3x3x3 region, this is
00638      *              the column of the found extremum using the coordinates of
00639      *              the corresponding level.
00640      * @param scale in case an extremum is found in the 3x3x3 region, this is
00641      *              the scale of the found extremum.
00642      *
00643      * @return the type of extremum detected.  In case a
00644      *         maximum/minimum was found, the spRow, spCol and scale  will 
00645      *         contain the position with sub-pixel precision of the found
00646      *         extremum.
00647      */
00648     eExtremaType interpolateExtremum(const int row, 
00649                                     const int col,
00650                                     const int level,
00651                                     float& spRow,
00652                                     float& spCol,
00653                                     float& scale) const;
00654 
00655 
00656     /**
00657      * Seaches the maximum with sub-pixel accuracy in a 3x3 region around the
00658      * access point.
00659      *
00660      * A 2D quadratic function will be used to compute the sub-pixel values.
00661      *
00662      * Note that in makes only sense to call this method if the (col,row)
00663      * point of the given level is already a maximum in the discrete
00664      * coordinates system, i.e. if the point is greater than its eight
00665      * neighbors.  Otherwise this method will just return false
00666      *
00667      * @param row row in coordinates of the given level, i.e. this value must
00668      *            be between 0 and at(level).rows()
00669      * @param col column in coordinates of the given level, i.e. this value
00670      *            must be between 0 and at(level).columns()
00671      * @param level level at which the maximum must be looked for.
00672      * @param spRow in case a maximum is found in the 3x3 region, this is the
00673      *              row of the found maximum using the coordinates of the 
00674      *              corresponding level. 
00675      * @param spCol in case a maximum is found in the 3x3 region, this is the
00676      *              column of the found maximum using the coordinates of the 
00677      *              corresponding level.
00678      *
00679      * @return true if a maximum was found within the 3x3 region.  In this case
00680      *         the spRow and spCol will contain the position with sub-pixel
00681      *         precision of the found maximum.  In case there is a maximum,
00682      *         but not in the 3x3 region, or only a minimum or saddle point
00683      *         is found, then false will be returned.
00684      */
00685     bool interpolateMaximum(const int row, 
00686                             const int col,
00687                             const int level,
00688                             float& spRow,
00689                             float& spCol) const;
00690 
00691     /**
00692      * Seaches the maximum with sub-pixel accuracy in a 3x3x3 region around the
00693      * access point.
00694      *
00695      * A 3D quadratic function will be used to compute the sub-pixel values.
00696      *
00697      * This function will only work if the parameters::factor is in ]0.5,1.0[.
00698      *
00699      * Note that in makes only sense to call this method if the (col,row)
00700      * point of the given level is already a maximum in the discrete
00701      * coordinates system, i.e. if the point is greater than its 26
00702      * neighbors.  Otherwise this method will just return false
00703      *
00704      * @param row row in coordinates of the given level, i.e. this value must
00705      *            be between 0 and at(level).rows()
00706      * @param col column in coordinates of the given level, i.e. this value
00707      *            must be between 0 and at(level).columns()
00708      * @param level level at which the maximum must be looked for.
00709      * @param spRow in case a maximum is found in the 3x3x3 region, this is 
00710      *              the row of the found extremum using the coordinates of 
00711      *              the corresponding level. 
00712      * @param spCol in case an maximum is found in the 3x3x3 region, this is
00713      *              the column of the found extremum using the coordinates of
00714      *              the corresponding level.
00715      * @param scale in case an maximum is found in the 3x3x3 region, this is
00716      *              the scale of the found extremum.
00717      *
00718      * @return true if a maximum was found within the 3x3 region.  In this case
00719      *         the spRow and spCol will contain the position with sub-pixel
00720      *         precision of the found maximum.  In case there is a maximum,
00721      *         but not in the 3x3 region, or only a minimum or saddle point
00722      *         is found, then false will be returned.
00723      */
00724     bool interpolateMaximum(const int row, 
00725                             const int col,
00726                             const int level,
00727                             float& spRow,
00728                             float& spCol,
00729                             float& scale) const;
00730 
00731     /**
00732      * Check if the given pixel at the given level (in the respective
00733      * coordinate system) is a maximum in the 3x3 neighborhood.
00734      *
00735      * @param row row of the point to be checked.  It must be between 0 and
00736      *            at(level).lastRow(), but for the borders false will be
00737      *            always returned, as a "constant boundary" will be always
00738      *            assumed.
00739      * @param col column of the point to be checked.  It must be between 0 and
00740      *            at(level).lastColumn(), but for the borders false will be
00741      *            always returned, as a "constant boundary" will be always
00742      *            assumed.
00743      * @param level the level where the maximum has to be checked.
00744      */ 
00745     bool checkMaximum(const int row,
00746                       const int col,
00747                       const int level) const;
00748     
00749     /**
00750      * Check if the given pixel at the given level (in the respective
00751      * coordinates) is a maximum in the 3x3x3 neighborhood
00752      *
00753      * @param row row of the point to be checked.  It must be between 0 and
00754      *            at(level).lastRow(), but for the borders false will be
00755      *            always returned, as a "constant boundary" will be always
00756      *            assumed.
00757      * @param col column of the point to be checked.  It must be between 0 and
00758      *            at(level).lastColumn(), but for the borders false will be
00759      *            always returned, as a "constant boundary" will be always
00760      *            assumed.
00761      * @param level the level where the maximum has to be checked.
00762      */ 
00763     bool checkInterlevelMaximum(const int row,
00764                                 const int col,
00765                                 const int level) const;
00766 
00767     /**
00768      * Map the coordinates of the given level into coordinates of level 0
00769      */
00770     inline void mapToLevel0(const int level,
00771                             const float row,
00772                             const float col,
00773                             float& row0,
00774                             float& col0) const;
00775 
00776     /**
00777      * Map the coordinates of level 0 into the coordinates of the given level
00778      */
00779     inline void mapToLevel(const int level,
00780                            const float& row0,
00781                            const float& col0,
00782                            float& row,
00783                            float& col) const;
00784     
00785     /**
00786      * Map the coordinates from level "from" to level "to"
00787      */
00788     inline void mapToLevel(const int fromLevel,
00789                            const int toLevel,
00790                            const float& rowFrom,
00791                            const float& colFrom,
00792                            float& rowTo,
00793                            float& colTo) const;
00794 
00795   protected:
00796     /**
00797      * Functor used for nearest neighbor interpolation
00798      */
00799     nearestNeighborInterpolator<value_type> nnIpl;
00800 
00801     /**
00802      * Functor used to bilinear interpolate
00803      */
00804     bilinearInterpolator<value_type> bilinIpl;
00805 
00806     /**
00807      * Functor used to biquadratic interpolate
00808      */
00809     biquadraticInterpolator<value_type> biquadIpl; 
00810 
00811     /**
00812      * Access with constant boundary
00813      */
00814     inline value_type cstAt(const T& img,const int y,const int x) const;
00815 
00816     /**
00817      * This "transparent" accumulator returns the first input value, while
00818      * it accumulates in the second variable
00819      */
00820     inline const value_type& tacc(const value_type& in,
00821                                   value_type& out) const;
00822 
00823   protected:
00824     /**
00825      * The parameters in use
00826      */
00827     parameters param;
00828 
00829     /**
00830      * Vector containing the real scaling factors used for each level in
00831      * the pyramid.
00832      */
00833     dvector levelFactor;
00834     
00835     /**
00836      * Initialize the values for the levelFactor. 
00837      * It assumes that the vector has the proper size.
00838      */
00839     void initLevelFactor();
00840 
00841   };
00842 
00843 
00844 }
00845 
00846 #include "ltiScaleSpacePyramid_template.h"
00847 #endif

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