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

ltiPyramidLocationSearch.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 .......: ltiPyramidLocationSearch.h
00027  * authors ....: Frederik Lange, Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 18.03.2003
00030  * revisions ..: $Id: ltiPyramidLocationSearch.h,v 1.4 2006/02/08 11:41:08 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_PYRAMID_LOCATION_SEARCH_H_
00034 #define _LTI_PYRAMID_LOCATION_SEARCH_H_
00035 
00036 #include "ltiImage.h"
00037 #include "ltiMath.h"
00038 #include "ltiTransform.h"
00039 #include "ltiLocation.h"
00040 #include "ltiScaleSpacePyramid.h"
00041 #include "ltiGradientFunctor.h"
00042 
00043 #include <list>
00044 #include <vector>
00045 #include <map>
00046 
00047 using std::list;
00048 using std::vector;
00049 
00050 namespace lti {
00051   /**
00052    * Search for salient locations in the scale space of a channel.
00053    *
00054    * The detected locations can be used to extract local features.
00055    *
00056    * For more information see:
00057    * David G. Lowe "Distinctive Image Features from Scale-Invariant Keypoints"
00058    * June, 2003
00059    *
00060    * This functor is more robust but also computationally more expensive than
00061    * its predecessor lti::axLocalRegions.
00062    *
00063    * The method is not 100% any of the variants published by Lowe, but it
00064    * got his name since the general principle is the one explain in the 
00065    * previously mentioned paper. 
00066    * 
00067    * One of the major differences with Lowe's approach is the use of a
00068    * scale-space pyramid where all levels has their own scale.  Lowe uses
00069    * the same size for all level within an octave.  The Gaussian smoothing is
00070    * done here only for the first level, and thereafter only the one required
00071    * to keep the downsampling valid.
00072    *
00073    * @see lti::axLocalRegions, lti::locationSelector,
00074    *      lti::localColorFeature, lti::axOGDFeature
00075    */
00076   class pyramidLocationSearch : public transform {
00077   public:
00078     /**
00079      * The parameters for the class pyramidLocationSearch
00080      */
00081     class parameters : public transform::parameters {
00082     public:
00083       /**
00084        * Default constructor
00085        */
00086       parameters();
00087 
00088       /**
00089        * Copy constructor
00090        * @param other the parameters object to be copied
00091        */
00092       parameters(const parameters& other);
00093 
00094       /**
00095        * Destructor
00096        */
00097       ~parameters();
00098 
00099       /**
00100        * Returns name of this type
00101        */
00102       const char* getTypeName() const;
00103 
00104       /**
00105        * Copy the contents of a parameters object
00106        * @param other the parameters object to be copied
00107        * @return a reference to this parameters object
00108        */
00109       parameters& copy(const parameters& other);
00110    
00111       /**
00112        * Copy the contents of a parameters object
00113        * @param other the parameters object to be copied
00114        * @return a reference to this parameters object
00115        */
00116       parameters& operator=(const parameters& other);
00117 
00118 
00119       /**
00120        * Returns a pointer to a clone of the parameters
00121        */
00122       virtual functor::parameters* clone() const;
00123 
00124       /**
00125        * Write the parameters in the given ioHandler
00126        * @param handler the ioHandler to be used
00127        * @param complete if true (the default) the enclosing begin/end will
00128        *        be also written, otherwise only the data block will be written.
00129        * @return true if write was successful
00130        */
00131       virtual bool write(ioHandler& handler,const bool complete=true) const;
00132 
00133       /**
00134        * Read the parameters from the given ioHandler
00135        * @param handler the ioHandler to be used
00136        * @param complete if true (the default) the enclosing begin/end will
00137        *        be also written, otherwise only the data block will be written.
00138        * @return true if write was successful
00139        */
00140       virtual bool read(ioHandler& handler,const bool complete=true);
00141 
00142 #     ifdef _LTI_MSC_6     
00143       /**
00144        * This function is required by MSVC only, as a workaround for a
00145        * very awful bug, which exists since MSVC V.4.0, and still by
00146        * V.6.0 with all bugfixes (so called "service packs") remains
00147        * there...  This method is also public due to another bug, so please
00148        * NEVER EVER call this method directly: use read() instead
00149        */
00150       bool readMS(ioHandler& handler,const bool complete=true);
00151 
00152       /**
00153        * This function is required by MSVC only, as a workaround for a
00154        * very awful bug, which exists since MSVC V.4.0, and still by
00155        * V.6.0 with all bugfixes (so called "service packs") remains
00156        * there...  This method is also public due to another bug, so please
00157        * NEVER EVER call this method directly: use write() instead
00158        */
00159       bool writeMS(ioHandler& handler,const bool complete=true) const;
00160 #     endif
00161 
00162       // ------------------------------------------------
00163       // the parameters
00164       // ------------------------------------------------
00165 
00166       /**
00167        * @name Scale-space pyramid options
00168        */
00169       //@{
00170       /**
00171        * Number of levels in the pyramid
00172        *
00173        * Default value: 15 (five octaves with the default levelScaleFactor)
00174        */
00175       int numLevels;
00176 
00177       /**
00178        * Lowe suggests to upsample the first level by a factor of two using
00179        * bilinear interpolation. 
00180        *
00181        * Here you can given the number of upsampled levels you want to
00182        * have in your pyramid.  Using the default levelScaleFactor you need
00183        * to set here 3 in order to get a first level upsampled a scaling
00184        * factor of exaclty 2.
00185        *
00186        * In general, the size of the first level will be the reciprocal of
00187        * levelScaleFactor to the power of upsampleFirstLevel, multiplied by
00188        * the size of the original channel.
00189        *
00190        * If you want to use the original channel as the highest
00191        * resolution level or the pyramid, set this parameter to \a 0.
00192        *
00193        * This value must be 0 or positive.
00194        *
00195        * Usually, the locations returned by the apply methods contain
00196        * coordinates in the original image. By setting the parameter
00197        * locationsAtLevelZero to \a true the location coordinates
00198        * relate to the channel at level \a 0 in the channel pyramid
00199        * (see getChannelPyramid()). This can be useful when the
00200        * location search is part of a feature extraction. The level \a
00201        * 0 channel is either the original image or the upsampled image
00202        * depending on the value or upsampleFirstLevel.
00203        *
00204        * Default value: 1 
00205        */
00206       int upsampleFirstLevel;
00207 
00208       /**
00209        * Parameters used in the pyramid.
00210        *
00211        * Lowe suggests to use scaling factors of the form 2^(-1/n),
00212        * meaning that one octave will be divided by an integer number n of
00213        * level.  His experiments suggest that the optimal value for n is 3.
00214        * The default value for this factor is 2^(-1/3) = 0.793700526.
00215        *
00216        * The scaling factor (factor) is set to 
00217        */
00218       scaleSpacePyramid<channel>::parameters pyramidParameters;
00219 
00220       /**
00221        * Set to \a true to enable subpixel interpolation in the determination
00222        * of scale space maxima.
00223        *
00224        * Default value: true
00225        */
00226       bool interpolateMaxima;
00227 
00228       /**
00229        * Set to true if only locations have to be accepted which have a 
00230        * saliency bigger than its upper and lower levels.
00231        *
00232        * Default value: false
00233        */
00234       bool checkInterLevelMaxima;
00235 
00236       /**
00237        * Value used for the smoothing kernel of only the first level.
00238        *
00239        * This corresponds to the variance of the kernel, and not to the
00240        * standard deviation.
00241        *
00242        * If you don't want any smoothing, set this value to zero.  The size
00243        * of the kernel will be computed automatically to have at the first
00244        * and last tabs values less than 5 percent of the middle tab.
00245        *
00246        * Default value: Lowe suggestion of 1.6^2 = 2.56 (kernel size 5)
00247        */
00248       float smoothingGaussianVariance;
00249 
00250       /**
00251        * Usually, the locations returned by the apply methods contain
00252        * coordinates in the original image. By setting the parameter
00253        * locationsAtLevelZero to \a true the location coordinates
00254        * relate to the channel at level \a 0 in the channel pyramid
00255        * (see getChannelPyramid()) instead. This can be useful when the
00256        * location search is part of a feature extraction. The level \a
00257        * 0 channel is either the original image or the upsampled image
00258        * depending on the value or upsampleFirstLevel.
00259        *
00260        * Default \a false
00261        *
00262        * \b NOTE: Usually, you will not want this option to be
00263        * activated. Be sure to fully understand the consequences
00264        * before you do.
00265        */
00266       bool locationsAtLevelZero;
00267       //@}
00268 
00269       /**
00270        * @name Maxima detection
00271        */
00272       //@{
00273       /**
00274        * The size of the neighborhood to search for maxima in one level.
00275        *
00276        * The accepted values are 3,5 or 7 (meaning 3x3, 5x5 or 7x7
00277        * neighborhoods).
00278        *
00279        * Default value: 3
00280        */
00281       int spatialMaximumNeighborhoodSize;
00282 
00283       /**
00284        * Modes available for the peak detection
00285        */
00286       enum ePeakSelectionMode {
00287         GradientMagnitude, /**< Magnitude of the gradient */
00288         Laplacian,         /**< Laplacian, using an lti::laplacianKernel */
00289         Harris,            /**< Harris corner detector */
00290         DoG                /**< Difference of Gaussians.  See doGLevelDistance
00291                                 for more information.*/
00292       };
00293 
00294       /**
00295        *  Method for peak selection:
00296        *  - GradientMagnitude 
00297        *  - Laplacian
00298        *  - Harris
00299        *  - DoG (Default and best)
00300        *
00301        * Default value: DoG
00302        */
00303       ePeakSelectionMode peakSelectionMode;
00304 
00305       /**
00306        * Scale distance for the difference of Gaussians.
00307        *
00308        * The Difference of Gaussians (DoG) peak detection mode needs to know
00309        * which levels it has to compare.  The default implementation compares
00310        * two adjacent levels, but this is not mandatory.  You can specify here
00311        * any integer greater or equal 1.
00312        *
00313        * The computation is done convolving each level with a precomputed
00314        * kernel, that considers this value and the doGVariance, so that the
00315        * computation times will be proportionally increasing with greater
00316        * values here and in doGVariance.
00317        *
00318        * The kernel \e K used will be:
00319        *
00320        * \f[ K(x,y) = G(x,y,k\sigma) - G(x,y,\sigma) \f]
00321        *
00322        * where \e G is a Gaussian function and \e k represents this
00323        * doGLevelDistance parameter.
00324        *
00325        * Default value: 1
00326        */
00327       int doGLevelDistance;
00328 
00329       /**
00330        * Variance for the Gaussian of the current level when using
00331        * the DoG peak detection mode.
00332        *
00333        * The size of the final kernel used can be indicated explicitely or
00334        * computed automatically depending on the value of doGKernelSize.
00335        *
00336        * Default value: 1.6*1.6
00337        */
00338       float doGKernelVariance;
00339 
00340       /**
00341        * Size of the kernel used to compute the DoG.
00342        *
00343        * If you set here a negative value, a kernel will be computed with a
00344        * size such that the taps of a Gaussian kernel with
00345        * variance doGLevelDistance*doGKernelVariance will be no greater than
00346        * 5\% of the the kernel tap at the position zero.
00347        *
00348        * If you don't want automatic computation of the kernel size, you
00349        * should set and odd value greater or equal 3.
00350        *
00351        * Default value: -1 (e.g. automatic size computation)
00352        */
00353       int doGKernelSize;
00354 
00355       /**
00356        * Minimum relative value for the allowed for a location to be salient.
00357        *
00358        * If the Laplacian pyramid (or its equivalent in other
00359        * peakDetectionMode) contains a value less than saliencyThreshold
00360        * times the maximum value at the corresponding pyramid level, then
00361        * that value will be ignored.
00362        *
00363        * If the number of levels in the pyramid is greater than the size
00364        * of these vector, to all "additional" levels, the last valid value
00365        * of the vector will be used.  This means, if the given vector is
00366        * of size one, then for all levels the same threshold will be used.
00367        *
00368        * Default value: vector<float>(1,0.1f), i.e. all levels will use 0.1f
00369        */
00370       vector<float> saliencyThreshold;
00371 
00372       /**
00373        * Edgeness Threshold.
00374        *
00375        * The edgeness is defined here as the ratio between the largest and the
00376        * smallest eigenvalues of the Hessian matrix.  This means, the smallest
00377        * possible edgeness value is one, when both eigenvalues are equal,
00378        * denoting a point with no definite edge direction, being a good
00379        * candidate for a stable salient point.  The larger the value, the
00380        * greater the probability that the salient value is an egde made 
00381        * salient by noise.
00382        *
00383        * Set the value closer to one to filter out edge point or larger to
00384        * tolerate edge induced locations.
00385        *
00386        * Default value 10;
00387        */
00388       float edgenessThreshold;
00389 
00390       /**
00391        * Density filter.
00392        *
00393        * There are many applications where a global saliency threshold for the
00394        * whole image is not appropriate.  In those cases, you usually set the
00395        * saliency threshold very low, so that in dark image regions some
00396        * locations can also be detected.
00397        *
00398        * The density filter activates a "local" saliency check.  First, all
00399        * locations are computed considering the saliencyThreshold only.  Then,
00400        * all locations "vote" with their saliency value in a window of radius
00401        * densityKernelRadius.  Voting means here, to assign all pixels in the
00402        * window the maximum value between the value they already had and the
00403        * saliency of the location.
00404        *
00405        * Only those locations will survive, which have a saliency value
00406        * greater or equal than the final "accumulated" saliency multiplied
00407        * with the corresponding level densityThreshold
00408        *
00409        * Default value: false
00410        */
00411       bool densityFilter;
00412 
00413       /**
00414        * Density Kernel Radius
00415        *
00416        * Radius of a circular region around a location for density check.  The
00417        * greater the number, the more competitive the saliency of a location
00418        * must be, in order to survive.
00419        *
00420        * Default value: 3
00421        */
00422       int densityKernelRadius;
00423 
00424       /**
00425        * Minimum relative value for the allowed for a location to be salient.
00426        *
00427        * A location will be considered salient only if the value at the final
00428        * local saliency estimation map multiplied by the corresponding
00429        * densityThreshold is smaller or equal the location saliency.
00430        *
00431        * If the number of levels in the pyramid is greater than the size
00432        * of these vector, to all "additional" levels, the last valid value
00433        * of the vector will be used.  This means, if the given vector is
00434        * of size one, then for all levels the same threshold will be used.
00435        *
00436        * Default value: vector<float>(1,0.75f), i.e. all levels will use 0.75f
00437        */
00438       fvector densityThreshold;
00439 
00440       //@}
00441 
00442       /**
00443        * @name Orientation detection
00444        */
00445       //@{
00446       /**
00447        * Radius of the orientation window
00448        *
00449        * The orientation will be analyzed at the nearest level corresponding
00450        * to the radius of a location.  The window used will have a size of
00451        * (1+2*orientationWindowRadius)^2.
00452        *
00453        * Default value: 3
00454        */
00455       int orientationWindowRadius;
00456 
00457       /**
00458        * Orientation sigma factor
00459        *
00460        * The values in the window are weighted with a Gaussian having as
00461        * standard deviation (sigma) the orientation window radius divided
00462        * by this factor.
00463        *
00464        * This value must always be greater than zero, or an unpredictible
00465        * behaviour must be expected.
00466        *
00467        * Default value: 2
00468        */
00469       float orientationSigmaFactor;
00470 
00471       /**
00472        * The resolution of the histogram for the determination of the
00473        * orientation of the location
00474        *
00475        * Default value: 36
00476        */
00477       int binsInOrientationHistogram;
00478 
00479       /**
00480        * Threshold used to accept multiple orientations.
00481        *
00482        * To compute the orientation of a location, a window with
00483        * orientationWindowRadius is used to compute an orientation histogram.
00484        * The greatest peak in this histogram determines the dominant
00485        * orientation.  However, if there are other peaks with a value equal
00486        * the greatest peak times this factor, then locations with their 
00487        * orientation will also be inserted in the location list.
00488        *
00489        * Set to 1.0 to detect only the maximum or maxima (if there are several
00490        * bins sharing the same maximal value), or greater than 1 if you want
00491        * only one maximum.  A value of zero or less will include a location
00492        * for all angles detected in the image (a much as
00493        * binsInOrientationHistogram).
00494        *
00495        * Default value: 0.8
00496        */
00497       float multiOrientationThreshold;
00498 
00499       /**
00500        * Average orientation
00501        *
00502        * If this value is set to true, all entries with values greater
00503        * than multiOrientationThreshold times the maximum entry will
00504        * be used to compute one single average value for the orientation.  Note
00505        * that no multi-oriented locations will be detected, but only one.
00506        *
00507        * If is set to false, the entries are used directly as orientations, as
00508        * Lowe suggested.
00509        *
00510        * Default value: false
00511        */
00512       bool averageOrientation;
00513 
00514       //@}
00515 
00516       /**
00517        * @name Location properties
00518        */
00519       //@{
00520       /**
00521        * This value indicates the scaling factor for a location radius.
00522        * 
00523        * In other words, this value will be multiplied with the corresponding
00524        * pixel radius of a scaling factor to obtain the location radius.
00525        *
00526        * Remember that the pixel radius at level 0 is 0.5;
00527        *
00528        * Default value: 7
00529        */
00530       float locationRelativeRadius;
00531       //@}
00532     };
00533 
00534     /**
00535      * Default constructor
00536      */
00537     pyramidLocationSearch();
00538 
00539     /**
00540      * Construct a functor using the given parameters
00541      */
00542     pyramidLocationSearch(const parameters& par);
00543 
00544     /**
00545      * Copy constructor
00546      * @param other the object to be copied
00547      */
00548     pyramidLocationSearch(const pyramidLocationSearch& other);
00549 
00550     /**
00551      * Destructor
00552      */
00553     virtual ~pyramidLocationSearch();
00554 
00555     /**
00556      * Returns the name of this type ("pyramidLocationSearch")
00557      */
00558     virtual const char* getTypeName() const;
00559   
00560     /**
00561      * @name Apply methods
00562      */
00563     //@{
00564 
00565     /**
00566      * Extracts the most relevant locations from the given channel, and return
00567      * them as list of lti::location objects.
00568      *
00569      * @param src channel with the source data.
00570      * @param locs list of relevant locations
00571      * @return true if apply successful or false otherwise.
00572      */
00573     bool apply(const channel& src,
00574                std::list<location>& locs);
00575 
00576     /**
00577      * Extracts the most relevant locations from the given channel, and return
00578      * them as list of lti::location objects.
00579      *
00580      * @param src channel with the source data.
00581      * @param locs list of relevant locations
00582      * @param totalLocs total number of detected locations
00583      * @return true if apply successful or false otherwise.
00584      */
00585     bool apply(const channel& src,
00586                std::list<location>& locs,
00587                int& totalLocs);
00588 
00589     /**
00590      * Extracts the most relevant locations from the given channel,
00591      * and return them as map where the key equals the level in which
00592      * the locations where found and the value is a list of
00593      * lti::location objects in that level.
00594      *
00595      * \b Note: This apply is faster than 
00596      * apply(const channel&,std::list<location>&).
00597      *
00598      * @param src channel with the source data.
00599      * @param locs map of lists of relevant locations per level
00600      * @return true if apply successful or false otherwise.
00601      */
00602     bool apply(const channel& src,std::map<int,std::list<location> >& locs);
00603 
00604     /**
00605      * Extracts the most relevant locations from the given channel,
00606      * and return them as map where the key equals the level in which
00607      * the locations where found and the value is a list of
00608      * lti::location objects in that level.
00609      *
00610      * \b Note: This apply is faster than 
00611      * apply(const channel&,std::list<location>&).
00612      *
00613      * @param src channel with the source data.
00614      * @param locs map of lists of relevant locations per level
00615      * @param totalLocs total number of detected locations
00616      * @return true if apply successful or false otherwise.
00617      */
00618     bool apply(const channel& src,
00619                std::map<int,std::list<location> >& locs,
00620                int& totalLocs);
00621 
00622 
00623     /**
00624      * Extracts the most relevant locations from both channels, and return
00625      * them as list of lti::location objects.
00626      *
00627      * @param c1 first color or other feature component
00628      * @param c2 second color or other feature component
00629      * @param locs list of relevant locations
00630      * @return true if apply successful or false otherwise.
00631      */
00632     bool apply(const channel& c1,
00633                const channel& c2,
00634                std::list<location>& locs);
00635 
00636     /**
00637      * Extracts the most relevant locations from both channels, and return
00638      * them as list of lti::location objects.
00639      *
00640      * @param c1 first color or other feature component
00641      * @param c2 second color or other feature component
00642      * @param locs list of relevant locations
00643      * @param totalLocs total number of detected locations
00644      * @return true if apply successful or false otherwise.
00645      */
00646     bool apply(const channel& c1,
00647                const channel& c2,
00648                std::list<location>& locs,
00649                int& totalLocs);
00650 
00651     /**
00652      * Extracts the most relevant locations from both channels,
00653      * and return them as map where the key equals the level in which
00654      * the locations where found and the value is a list of
00655      * lti::location objects in that level.
00656      *
00657      * \b Note: This apply is faster than 
00658      * apply(const channel&,std::list<location>&).
00659      *
00660      * @param c1 first color or other feature component
00661      * @param c2 second color or other feature component
00662      * @param locs map of lists of relevant locations per level
00663      * @return true if apply successful or false otherwise.
00664      */
00665     bool apply(const channel& c1,const channel& c2,
00666                std::map<int,std::list<location> >& locs);
00667 
00668     /**
00669      * Extracts the most relevant locations from both channels,
00670      * and return them as map where the key equals the level in which
00671      * the locations where found and the value is a list of
00672      * lti::location objects in that level.
00673      *
00674      * \b Note: This apply is faster than 
00675      * apply(const channel&,std::list<location>&).
00676      *
00677      * @param c1 first color or other feature component
00678      * @param c2 second color or other feature component
00679      * @param locs map of lists of relevant locations per level
00680      * @param totalLocs total number of detected locations
00681      * @return true if apply successful or false otherwise.
00682      */
00683     bool apply(const channel& c1,const channel& c2,
00684                std::map<int,std::list<location> >& locs,
00685                int& totalLocs);
00686 
00687     /**
00688      * Extracts the most relevant locations from the given channel, and return
00689      * them as list of lti::location objects.
00690      *
00691      * @param c1 first color or other feature component
00692      * @param c2 second color or other feature component
00693      * @param c3 third color or other feature component
00694      * @param locs list of relevant locations
00695      * @return true if apply successful or false otherwise.
00696      */
00697     bool apply(const channel& c1,const channel& c2,const channel& c3,
00698                std::list<location>& locs);
00699 
00700     /**
00701      * Extracts the most relevant locations from the given channel, and return
00702      * them as list of lti::location objects.
00703      *
00704      * @param c1 first color or other feature component
00705      * @param c2 second color or other feature component
00706      * @param c3 third color or other feature component
00707      * @param locs list of relevant locations
00708      * @param totalLocs total number of detected locations
00709      * @return true if apply successful or false otherwise.
00710      */
00711     bool apply(const channel& c1,const channel& c2,const channel& c3,
00712                std::list<location>& locs,
00713                int& totalLocs);
00714 
00715     /**
00716      * Extracts the most relevant locations from the given channel,
00717      * and return them as map where the key equals the level in which
00718      * the locations where found and the value is a list of
00719      * lti::location objects in that level.
00720      *
00721      * \b Note: This apply is faster than 
00722      * apply(const channel&,std::list<location>&).
00723      *
00724      * @param c1 first color or other feature component
00725      * @param c2 second color or other feature component
00726      * @param c3 third color or other feature component
00727      * @param locs map of lists of relevant locations per level
00728      * @return true if apply successful or false otherwise.
00729      */
00730     bool apply(const channel& c1,const channel& c2,const channel& c3,
00731                std::map<int,std::list<location> >& locs);
00732 
00733     /**
00734      * Extracts the most relevant locations from the given channel,
00735      * and return them as map where the key equals the level in which
00736      * the locations where found and the value is a list of
00737      * lti::location objects in that level.
00738      *
00739      * \b Note: This apply is faster than 
00740      * apply(const channel&,std::list<location>&).
00741      *
00742      * @param c1 first color or other feature component
00743      * @param c2 second color or other feature component
00744      * @param c3 third color or other feature component
00745      * @param locs map of lists of relevant locations per level
00746      * @param totalLocs total number of detected locations
00747      * @return true if apply successful or false otherwise.
00748      */
00749     bool apply(const channel& c1,const channel& c2,const channel& c3,
00750                std::map<int,std::list<location> >& locs,
00751                int& totalLocs);
00752 
00753     //@}
00754 
00755 #if 0
00756     /**
00757      * @name Apply masked methods.
00758      *
00759      * Some times, you know that some part of the images will contain
00760      * locations although the contrast or saliency is very low, while other
00761      * sections should be "suppressed", independently of their saliency values.
00762      *
00763      * This family of apply methods allow you to specify a mask (lti::channel)
00764      * that specify the expected maximal saliency.
00765      *
00766      * The threshold that a location's saliency value has to surpass is
00767      * the one used in the normal apply() methods multiplied by the value
00768      * in the corresponding pixel of the given mask.  Thus, the pixels masked
00769      * with zero will produce all possible locations; the pixels masked with
00770      * one will behave as in the normal applies; pixels with values greater
00771      * than one will suppress locations (compared with the normal case).
00772      *
00773      * The simplest mask contains a strongly smoothed intensity channel of
00774      * the image, normalize to have as maximum value 1.0.  Additionaly, if
00775      * a background segmentation is available, those values can be set to
00776      * std::numeric_limits<float>::max() in order to suppress all background
00777      * locations.
00778      *
00779      * The mask is always the last argument.  Otherwise, they could not be
00780      * distinguished from the normal apply methods.
00781      */
00782     //@{
00783     /**
00784      * Extracts the most relevant locations from the given channel, and return
00785      * them as list of lti::location objects.
00786      *
00787      * @param src channel with the source data.
00788      * @param locs list of relevant locations
00789      * @param mask saliency suppression mask
00790      * @return true if apply successful or false otherwise.
00791      */
00792     bool apply(const channel& src,              
00793                std::list<location>& locs,
00794                const channel& mask);
00795 
00796     /**
00797      * Extracts the most relevant locations from the given channel, and return
00798      * them as list of lti::location objects.
00799      *
00800      * @param src channel with the source data.
00801      * @param mask saliency suppression mask
00802      * @param locs list of relevant locations
00803      * @param totalLocs total number of detected locations
00804      * @return true if apply successful or false otherwise.
00805      */
00806     bool apply(const channel& src,               
00807                std::list<location>& locs,
00808                int& totalLocs,
00809                const channel& mask);
00810     
00811     /**
00812      * Extracts the most relevant locations from the given channel,
00813      * and return them as map where the key equals the level in which
00814      * the locations where found and the value is a list of
00815      * lti::location objects in that level.
00816      *
00817      * \b Note: This apply is faster than 
00818      * apply(const channel&,std::list<location>&).
00819      *
00820      * @param src channel with the source data.
00821      * @param mask saliency suppression mask
00822      * @param locs map of lists of relevant locations per level
00823      * @return true if apply successful or false otherwise.
00824      */
00825     bool apply(const channel& src,
00826                std::map<int,std::list<location> >& locs,
00827                const channel& mask);
00828 
00829     /**
00830      * Extracts the most relevant locations from the given channel,
00831      * and return them as map where the key equals the level in which
00832      * the locations where found and the value is a list of
00833      * lti::location objects in that level.
00834      *
00835      * \b Note: This apply is faster than 
00836      * apply(const channel&,std::list<location>&).
00837      *
00838      * @param src channel with the source data.
00839      * @param locs map of lists of relevant locations per level
00840      * @param totalLocs total number of detected locations
00841      * @return true if apply successful or false otherwise.
00842      */
00843     bool apply(const channel& src,
00844                std::map<int,std::list<location> >& locs,
00845                int& totalLocs,
00846                const channel& mask);
00847 
00848     //@}
00849 
00850 #endif
00851       
00852     /**
00853      * Copy data of "other" functor.
00854      * @param other the functor to be copied
00855      * @return a reference to this functor object
00856      */
00857     pyramidLocationSearch& copy(const pyramidLocationSearch& other);
00858 
00859     /**
00860      * Alias for copy member
00861      * @param other the functor to be copied
00862      * @return a reference to this functor object
00863      */
00864     pyramidLocationSearch& operator=(const pyramidLocationSearch& other);
00865 
00866     /**
00867      * Returns a pointer to a clone of this functor.
00868      */
00869     virtual functor* clone() const;
00870 
00871     /**
00872      * Returns used parameters
00873      */
00874     const pyramidLocationSearch::parameters& getParameters() const;
00875 
00876     /**
00877      * @name Read-only access to the created pyramids in an apply method.
00878      *
00879      * This methods are used not only for debugging purposes, but also
00880      * to save some time with the computation of a channel pyramid, which
00881      * is usually employed in the computation of features.
00882      */
00883     //@{
00884     /**
00885      * Return the saliency pyramid of the last channel of the last apply
00886      *
00887      * Note that the multi-channel apply-methods use only one pyramid for
00888      * all channels, and therefore only the last one is kept.
00889      */
00890     const scaleSpacePyramid<channel>& getSaliencyPyramid() const;
00891 
00892     /**
00893      * Return the orientation pyramid of the last channel of the last apply
00894      *
00895      * Note that the multi-channel apply-methods use only one pyramid for
00896      * all channels, and therefore only the last one is kept.
00897      */
00898     const scaleSpacePyramid<channel>& getOrientationPyramid() const;
00899 
00900     /**
00901      * Return the input channel pyramid of the last channel of the last apply
00902      *
00903      * Note that the multi-channel apply-methods use only one pyramid for
00904      * all channels, and therefore only the last one is kept.
00905      */
00906     const scaleSpacePyramid<channel>& getChannelPyramid() const;
00907 
00908     //@}
00909 
00910 
00911   protected:
00912 
00913     /**
00914      * @name Saliency Methods
00915      */
00916     //@{
00917     /**
00918      * Applies the edge and/or corner extraction to the source souce channel
00919      * based on Laplace-Operator
00920      * 
00921      */
00922     void applyLaplacian(const channel& src, channel& dest) const ;
00923 
00924     /**
00925      * Extracts the magnitude and angle of the gradient for the given
00926      * for the given channel.
00927      *
00928      * @param src original channel
00929      * @param mag magnitude of the gradient
00930      * @param angle angle of the gradient.
00931      */
00932     void applyMag(const channel& src,
00933                   channel& mag,
00934                   channel& angle) const;
00935 
00936     /**
00937      * Applies the Harris cornerness extraction to the source souce channel
00938      * this is a measure for the curvature at a pixel
00939      */
00940     void applyCornerness(const channel& src, channel& dest) const;
00941 
00942     /**
00943      * Applies a DoG kernel to the given channel
00944      */
00945     void applyDoG(const channel& src, channel& dest) const;
00946     //@}
00947     
00948     /**
00949      * The required pyramids
00950      */
00951     //@{
00952     /**
00953      * Pyramid of original channel.
00954      */
00955     scaleSpacePyramid<channel> iPyr;
00956 
00957     /**
00958      * Pyramid of Laplacians, DoG, Harris cornerness, or gradient magnitude,
00959      * depending on the mode selected in the parameters.
00960      */
00961     scaleSpacePyramid<channel> lapPyr;
00962 
00963     /**
00964      * Vector containing the maxima at each level of the pyramid
00965      */
00966     fvector lapMax;
00967 
00968     /**
00969      * Pyramid containing the angles of the gradient, used to compute
00970      * the rotation of each feature.
00971      */
00972     scaleSpacePyramid<channel> argPyr;
00973 
00974     /**
00975      * Pyramid containing the magnitude of the gradient
00976      */
00977     scaleSpacePyramid<channel> magPyr;
00978 
00979     /**
00980      * Pyramid with maxima detected in the lapPyr.  
00981      *
00982      * This pyramid will only be initialized if the spatial maximum
00983      * neighborhood is greater than 3.
00984      */
00985     scaleSpacePyramid<channel> maxPyr;
00986     
00987     /**
00988      * First level factor
00989      *
00990      * If the pyramid was upsampled, this is the factor with which the
00991      * first level was created.
00992      */
00993     double firstLevelFactor;
00994     //@}
00995 
00996     /**
00997      * Functor used to compute gradients
00998      */
00999     gradientFunctor gradient;
01000 
01001     /**
01002      * Compute the doGKernel as wished by the user.
01003      */
01004     bool computeDoGKernel();
01005 
01006     /**
01007      * Kernel used to compute the DoG
01008      */
01009     sepKernel<float> doGKernel;
01010 
01011     /**
01012      * @name Apply helper methods
01013      */
01014     //@{
01015     /**
01016      * Compute the pyramids
01017      */
01018     bool computePyramids(const channel& src);
01019 
01020     /**
01021      * Compute the position of the locations for each level, based on
01022      * the pyramids
01023      */
01024     bool
01025     computeLocationsPosition(std::map< int, std::list<location> >& locMap);
01026 
01027     /**
01028      * Compute the orientation of each location in each level.
01029      *
01030      * The total number of locations is also computed
01031      */
01032     bool
01033     computeLocationOrientation(std::map< int, std::list<location> >& locMap,
01034                                int& totalLocs);
01035     //@}
01036 
01037     /**
01038      * Compute the maximum for the given three values, assuming that the
01039      * middle value has an offset of zero and using a quadratic function 
01040      * that passes through all three points.
01041      *
01042      * The returned value \a x will be between -1.0 and 1.0 if a maximum 
01043      * was detected, or will remain untouched if no maximum was found.  If
01044      * a maximum is found, the function returns true.
01045      */
01046     inline bool qmaximum(const float ym1,const float y0,const float y1,
01047                          float& x) const;
01048 
01049     /**
01050      * Compute the angle given an index.  It will use the neighbors to
01051      * compute the position of the maximum.
01052      */
01053     float getAngle(const vector<float>& angles,
01054                    const int idx) const;
01055 
01056     /**
01057      * Compute the edgeness ratio. 
01058      *
01059      * The value computed here corresponds to the Tr(H)^2/Det(H), with
01060      * the Hessian matrix H.
01061      *
01062      * This method expects x and y to be greater 1 and to be not larger than
01063      * 1 minus the last valid index bei each coordinate.
01064      */
01065     float edgenessRatio(const channel& chnl,
01066                         const int y,
01067                         const int x) const;
01068     
01069 
01070     /**
01071      * Transport all data in the second map into the first one, without
01072      * copying it.
01073      * 
01074      * At the end of the operation the second map will be empty.
01075      */
01076     void concatLocsMap(std::map<int,std::list<location> >& src1dest,
01077                        std::map<int,std::list<location> >& src2) const;
01078 
01079     /**
01080      * Density filter
01081      *
01082      * If the saliency threshold is too low, too many locations will be
01083      * detected.  The density filter chooses the most salient locations such
01084      * that in the radio of each level no more than 
01085      *
01086      */
01087     bool densityFilter(std::map<int,std::list<location> >& srcDest) const;
01088   };
01089 }
01090 
01091 #endif

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