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

ltiLocationSearchEvaluation.h

00001 /*
00002  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
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 .......: ltiLocationSearchEvaluation.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 25.11.2003
00030  * revisions ..: $Id: ltiLocationSearchEvaluation.h,v 1.2 2007/04/09 12:15:44 alvarado Exp $
00031  */
00032 
00033 #ifndef _LTI_LOCATION_SEARCH_EVALUATION_TESTER_H_
00034 #define _LTI_LOCATION_SEARCH_EVALUATION_TESTER_H_
00035 
00036 #include "ltiKdTree.h"
00037 #include "ltiParetoFront.h"
00038 #include "ltiPyramidLocationSearch.h"
00039 
00040 namespace lti {
00041 
00042   /**
00043    * Pareto evaluation of the lti::pyramidLocationSearch functor.
00044    *
00045    * This class tests the parameterization of the lti::pyramidLocationSearch
00046    * functor by searching the Pareto front of some fittness measures, using
00047    * the genetic search framework provided by the paretoFront class.
00048    *
00049    * The fitness criteria used here are:
00050    * - number of locations
00051    * - reciprocal of location  number (1/number of locations)
00052    * - number of occupied levels in the pyramid
00053    * - reciprocal of the time taken to extract all locations
00054    * - scale repeatability, i.e. considering scale changes only
00055    * - rotation repeatability, i.e. considering rotations only
00056    * - rotation scale repeatability, i.e. considering scale and rotation 
00057    * - scale stable locations, i.e. considering scale changes only
00058    * - rotation stable locations, i.e. considering rotations only
00059    * - rotation scale stable locations, i.e. considering scale and rotation 
00060    * 
00061    * For the evaluation of a parameterization the algorithm takes all
00062    * images stored in the file specified in parameters::images.  For
00063    * each one of them a set of rotations and scalings are applied, to
00064    * the image and the locations estracted from it.  Since the geometric
00065    * transformation is known, we have a "should-be" set of locations, obtained
00066    * transforming the original image locations.  This set is compared with
00067    * the locations extracted from the transformed image.  The correspondences
00068    * are counted and they constitute in percentage the fitness measure.
00069    *
00070    * The "repeatability" measures equal the "stable locations"  normalized
00071    * by the total number of locations.
00072    */
00073   class locationSearchEvaluation : public paretoFront {
00074   public:
00075 
00076     /**
00077      * The parameters for the class locationSearchEvaluation
00078      */
00079     class parameters : public paretoFront::parameters {
00080     public:
00081       /**
00082        * Default constructor
00083        */
00084       parameters();
00085 
00086       /**
00087        * Copy constructor
00088        * @param other the parameters object to be copied
00089        */
00090       parameters(const parameters& other);
00091 
00092       /**
00093        * Destructor
00094        */
00095       ~parameters();
00096 
00097       /**
00098        * Returns name of this type
00099        */
00100       const char* getTypeName() const;
00101 
00102       /**
00103        * Copy the contents of a parameters object
00104        * @param other the parameters object to be copied
00105        * @return a reference to this parameters object
00106        */
00107       parameters& copy(const parameters& other);
00108 
00109       /**
00110        * Copy the contents of a parameters object
00111        * @param other the parameters object to be copied
00112        * @return a reference to this parameters object
00113        */
00114       parameters& operator=(const parameters& other);
00115 
00116 
00117       /**
00118        * Returns a pointer to a clone of the parameters
00119        */
00120       virtual functor::parameters* clone() const;
00121 
00122       /**
00123        * Write the parameters in the given ioHandler
00124        * @param handler the ioHandler to be used
00125        * @param complete if true (the default) the enclosing begin/end will
00126        *        be also written, otherwise only the data block will be written.
00127        * @return true if write was successful
00128        */
00129       virtual bool write(ioHandler& handler,const bool& complete=true) const;
00130 
00131       /**
00132        * Read the parameters from the given ioHandler
00133        * @param handler the ioHandler to be used
00134        * @param complete if true (the default) the enclosing begin/end will
00135        *        be also written, otherwise only the data block will be written.
00136        * @return true if write was successful
00137        */
00138       virtual bool read(ioHandler& handler,const bool& complete=true);
00139 
00140 #     ifdef _LTI_MSC_6
00141       /**
00142        * This function is required by MSVC only, as a workaround for a
00143        * very awful bug, which exists since MSVC V.4.0, and still by
00144        * V.6.0 with all bugfixes (so called "service packs") remains
00145        * there...  This method is also public due to another bug, so please
00146        * NEVER EVER call this method directly: use read() instead
00147        */
00148       bool readMS(ioHandler& handler,const bool& complete=true);
00149 
00150       /**
00151        * This function is required by MSVC only, as a workaround for a
00152        * very awful bug, which exists since MSVC V.4.0, and still by
00153        * V.6.0 with all bugfixes (so called "service packs") remains
00154        * there...  This method is also public due to another bug, so please
00155        * NEVER EVER call this method directly: use write() instead
00156        */
00157       bool writeMS(ioHandler& handler,const bool& complete=true) const;
00158 #     endif
00159 
00160       // ------------------------------------------------
00161       // the parameters
00162       // ------------------------------------------------
00163 
00164       /**
00165        * @name Fitness measures
00166        *
00167        * Value containing the 1D fitness measures to be computed.
00168        * The constants defined here are:
00169        * - numberOfLocations
00170        * - locationsReciprocal (1/number of locations)
00171        * - occupiedLevels
00172        * - time
00173        * - scaleRepeatability
00174        * - rotationRepeatability
00175        * - rotationScaleRepeatability
00176        * - scaleStable
00177        * - rotationStable
00178        * - rotationScaleStable
00179        *
00180        * This sequence is important, since it determines the positions of
00181        * the single measures in the fitness output vector.
00182        *
00183        * If more fitness measures are selected than the inherited parameter
00184        * fitnessSpaceDimensionality, then the first ones in this sequence
00185        * will be selected.
00186        *
00187        * If less fitness measure are selected than the inherited parameter
00188        * fitnessSpaceDimensionality, then the rest of the vector will be
00189        * filled with zeros.
00190        *
00191        * The difference between the "*Repeatibility" and the "*Stable" measures
00192        * is that the first ones are the number of stable locations normalized
00193        * to the total number of locations, i.e. their maximal value will be
00194        * always 1.0.  The "*Stable" unnormalized fitness measures may be
00195        * important to optimize in those applications that require many 
00196        * stable locations to work, and not only the major part of them.
00197        */
00198       //@{
00199       /** 
00200        * Total number of locations detected per image.
00201        *
00202        * Default value: false
00203        */
00204       bool numberOfLocations;
00205 
00206       /**
00207        * Locations' reciprocal
00208        *
00209        * This is the inverse of the number of location (1/number of locations).
00210        * It is often better to search of parameterizations that produce a 
00211        * low number of locations.  The used value will be 1/(1+\#locs) to avoid
00212        * divisions by zero.
00213        *
00214        * Default value: false
00215        */
00216       bool locationsReciprocal;
00217 
00218       /**
00219        * Percentage of generated levels with locations.  Useful to detect how
00220        * many levels are really necessary.
00221        *
00222        * Default value: false
00223        */
00224       bool occupiedLevels;
00225       
00226       /**
00227        * Mean time required to extract the locations
00228        *
00229        * Default value: true
00230        */
00231       bool time;
00232 
00233       /**
00234        * Repeatability considering only image scaling
00235        *
00236        * Default value: false
00237        */
00238       bool scaleRepeatability;
00239 
00240       /**
00241        * Repeatability considering only image rotation 
00242        *
00243        * Default value: false
00244        */
00245       bool rotationRepeatability; 
00246       
00247       /**
00248        * Repeatability considering both rotation and scaling
00249        *
00250        * Default value: true
00251        */
00252       bool rotationScaleRepeatability;
00253 
00254       /**
00255        * Absolute number of stable locations considering only image scaling
00256        *
00257        * Default value: false
00258        */
00259       bool scaleStable;
00260 
00261       /**
00262        * Absolute number of stable locations considering only image rotation 
00263        *
00264        * Default value: false
00265        */
00266       bool rotationStable; 
00267       
00268       /**
00269        * Absolute number of stable locations considering both rotation and
00270        * scaling
00271        *
00272        * Default value: true
00273        */
00274       bool rotationScaleStable;
00275 
00276       //@}
00277 
00278       /**
00279        * Name of a file containing all images to be analyzed.
00280        *
00281        * Default value: "images.txt"
00282        */
00283       std::string images;
00284 
00285       /**
00286        * Mask posfix
00287        *
00288        * For each image file in \a images, a manual segmented mask can
00289        * be used to ignore those locations outside the objects of interest.
00290        *
00291        * The filename of the masks will be assumed to be the same
00292        * image name with the given postfix.  For example, if a image is
00293        * called "test.png" and the postfix is "-preseg", then the
00294        * mask will be assumed to be "test-preseg.png".
00295        *
00296        * Default value: "_premask"
00297        */
00298       std::string postfix;
00299 
00300       /**
00301        * Values for all parameters of the pyramidLocationSearch functor
00302        * that will be used as minima.
00303        * 
00304        * Default value:
00305        *          numLevels 4
00306        *          upsampleFirstLevel 0
00307        *          pyramidParameters::factor 0.5
00308        *          pyramidParameters::gaussian false
00309        *          pyramidParameters::interpolatorType BilinearInterpolator
00310        *          interpolateMaxima false
00311        *          smoothingGaussianVariance 0
00312        *          spatialMaximumNeighborhoodSize 3
00313        *          peakSelectionMode GradientMagnitude
00314        *          doGLevelDistance 1
00315        *          doGKernelVariance 1
00316        *          saliencyThreshold 0
00317        *          edgenessThreshold 2
00318        *          orientationWindowRadius = 2
00319        */
00320       pyramidLocationSearch::parameters minValues;
00321 
00322       /**
00323        * Values for all parameters of the pyramidLocationSearch functor
00324        * that will be used as minima.
00325        * 
00326        * Default value:
00327        *          numLevels 30
00328        *          upsampleFirstLevel 3
00329        *          pyramidParameters::factor pow(0.5,1.0/8.0)
00330        *          pyramidParameters::gaussian true
00331        *          pyramidParameters::interpolatorType BiquadraticInterpolator
00332        *          interpolateMaxima true
00333        *          smoothingGaussianVariance 5
00334        *          spatialMaximumNeighborhoodSize 7
00335        *          peakSelectionMode DoG
00336        *          doGLevelDistance 4
00337        *          doGKernelVariance 4
00338        *          saliencyThreshold 0.99
00339        *          edgenessThreshold 10
00340        *          orientationWindowRadius = 5
00341        */
00342       pyramidLocationSearch::parameters maxValues;
00343 
00344       /**
00345        * Additive angle change.
00346        *
00347        * The interval from firstAngle to lastAngle will be divided in
00348        * subintervals with a width stepAngle.
00349        *
00350        * This must be given in radians, but if you give a value greater than
00351        * 2*Pi, it will be assumed to be in degrees.
00352        *
00353        * Default value: lti::degToRad(10), i.e. 10 degrees in radians.
00354        */
00355       float stepAngle;
00356 
00357       /**
00358        * Multiplicative scaling change.
00359        *
00360        * The scaling interval will begin with firstScaling, which will be
00361        * multiplied each type by stepScaling until last scaling is reached.
00362        *
00363        * This value must be greater than 1.
00364        *
00365        * Default value: sqrt(2)
00366        */
00367       float stepScaling;
00368 
00369       /**
00370        * First scaling of the image will downsample it by a factor of 4
00371        *
00372        * Default value: 0.25
00373        */
00374       float firstScaling;
00375 
00376       /**
00377        * Last scaling of the image will be an upsampling by a factor of 2
00378        *
00379        * Default value: 2
00380        */
00381       float lastScaling;
00382 
00383       /**
00384        * First angle
00385        *
00386        * This must be given in radians, but if you give a value greater than
00387        * 2*Pi, it will be assumed to be in degrees.
00388        *
00389        * Default value 0
00390        */
00391       float firstAngle;
00392 
00393       /**
00394        * Last rotation angle
00395        *
00396        * This must be given in radians, but if you give a value greater than
00397        * 2*Pi, it will be assumed to be in degrees.
00398        *
00399        * Default value: 2*Pi
00400        */
00401       float lastAngle;
00402 
00403       /**
00404        * If true, a location will be considered to match only if position AND
00405        * rotation lie within the tolerance levels.  If false, only the position
00406        * will be considered while analyzing the repeatability
00407        *
00408        * Default value: true
00409        */
00410       bool considerAngle;
00411 
00412       /**
00413        * Tolerance for scale deviation.
00414        *
00415        * Between two candidate matching locations, the match will be accepted
00416        * only if the ratio between scale of both locations does not goes
00417        * beneath the given tolerance value, which must be always smaller than
00418        * one.
00419        * 
00420        * Default value: 1/sqrt(2)
00421        */
00422       float scaleTolerance;
00423 
00424       /**
00425        * Tolerance for position deviation.
00426        *
00427        * Between two candidate matching locations, the match will be accepted
00428        * only if the distance between both locations does not exceed the given
00429        * tolerance value, which must be always positive.
00430        * 
00431        * Default value: 1.5f
00432        */
00433       float positionTolerance;
00434 
00435       /**
00436        * Angular tolerance.
00437        *
00438        * Two locations, which coincide in position and scale, match together
00439        * if the angular difference is smaller than the given angle.
00440        * 
00441        * This must be given in radians, but if you give a value greater than
00442        * 2*Pi, it will be assumed to be in degrees.
00443        *
00444        * Default value: lti::degToRad(10), i.e. 10 degrees in radians.
00445        */
00446       float angleTolerance;
00447     };
00448 
00449     /**
00450      * Default constructor
00451      */
00452     locationSearchEvaluation();
00453 
00454     /**
00455      * Construct a functor using the given parameters
00456      */
00457     locationSearchEvaluation(const parameters& par);
00458 
00459     /**
00460      * Copy constructor
00461      * @param other the object to be copied
00462      */
00463     locationSearchEvaluation(const locationSearchEvaluation& other);
00464 
00465     /**
00466      * Destructor
00467      */
00468     virtual ~locationSearchEvaluation();
00469 
00470     /**
00471      * Returns the name of this type ("locationSearchEvaluation")
00472      */
00473     virtual const char* getTypeName() const;
00474 
00475     /**
00476      * Returns a pointer to a clone of this functor.
00477      */
00478     virtual functor* clone() const;
00479 
00480     /**
00481      * Returns used parameters
00482      */
00483     const parameters& getParameters() const;
00484 
00485     /**
00486      * Set parameters
00487      */
00488     bool setParameters(const functor::parameters& par);
00489 
00490     /**
00491      * @name Public methods to be reimplemented
00492      */
00493     //@{
00494 
00495     /**
00496      * Convert a binary-chain representation of a chromosome to a valid
00497      * parameter object.
00498      */
00499     virtual bool chromosomeToPhenotype(const chromosome& genotype,
00500                                        functor::parameters& phenotype) const;
00501 
00502     /**
00503      * Return a fresh allocated parameters for the evaluated functor, which is
00504      * equivalent to the given genotype.
00505      */
00506     virtual functor::parameters* 
00507     chromosomeToPhenotype(const chromosome& genotype) const;
00508 
00509     /**
00510      * Convert a valid parameters object (phenotype) into binary-chain
00511      * representation of a chromosome.
00512      */
00513     virtual bool phenotypeToChromosome(const functor::parameters& phenotype,
00514                                        chromosome& genotype) const;
00515 
00516     /**
00517      * Return the length in bits for a chromosome.
00518      *
00519      * This method needs to be reimplemented, in order to get some 
00520      * default implementations to work.
00521      */
00522     virtual int getChromosomeSize() const;
00523 
00524     /**
00525      * Evaluate Chromosome
00526      *
00527      * This method is one of the most important ones for the pareto evaluation.
00528      * Its task is to produce a multidimensional fitness measure for a given
00529      * chromosome.
00530      *
00531      * It returns true if the evaluation was successful, of false if the
00532      * phenotype represents some invalid parameterization.  It is highly 
00533      * recomended that the mutation and crossover methods are reimplemented to 
00534      * avoid invalid parameterizations.
00535      */
00536     virtual bool evaluateChromosome(const chromosome& individual,
00537                                     dvector& fitness); 
00538 
00539     //@}
00540 
00541     /**
00542      * @name Evaluation Functions
00543      *
00544      * The real evaluation is provided here in order to compute measures
00545      * independently of the Pareto Front.
00546      */
00547     //@{
00548     /**
00549      * Index names for the complete multidimensional fitness measure
00550      */
00551     enum {
00552       IdxTime,              /**< Well, this is not really time, because that
00553                              *   would be "cost" instead of "fitness", in
00554                              *   reality, * this dimension contains 1.0/time in
00555                              *   s^-1, meaning the number of complete
00556                              *   location extractions per second.
00557                              */
00558       IdxNumberOfLocations, /**< Mean number of extracted locations 
00559                              */
00560       IdxLocationsRecip,    /**< Location reciprocal.
00561                              *
00562                              *   Inverse of the number of locations detected.
00563                              */
00564       IdxOccupiedLevels,    /**< Mean number of occupied levels.
00565                              */
00566       IdxScalePosRep,       /**< Scale repeatability defined as total
00567                              *   number of stable locations divided by
00568                              *   the total number of locations for
00569                              *   changes of scaling only.
00570                              */
00571       IdxRotationPosRep,    /**< Rotation repeatability defined as
00572                              *   total number of stable locations
00573                              *   divided by the total number of
00574                              *   locations for changes in the rotation
00575                              *   only.
00576                              */
00577       IdxRSPosRep,          /**< Rotation repeatability defined as
00578                              *   total number of stable locations
00579                              *   divided by the total number of
00580                              *   locations for changes in the rotation
00581                              *   and scale. This will only be computed
00582                              *   if the RSRepeatability bit in the parameters
00583                              *   is enabled (it costs too much time!).
00584                              */
00585       IdxScaleARep,         /**< Scale angular repeatability defined as
00586                              *   total number of angular stable
00587                              *   locations divided by the total number
00588                              *   of locations for changes of scaling
00589                              *   only.
00590                              */
00591       IdxRotationARep,      /**< Rotation angular repeatability defined
00592                              *   as total number of angular stable
00593                              *   locations divided by the total number
00594                              *   of locations for changes in the
00595                              *   rotation only.
00596                              */
00597       IdxRSARep,            /**< Angular repeatability defined as total
00598                              *   number of angular stable locations
00599                              *   divided by the total number of
00600                              *   locations for changes in the rotation
00601                              *   and scale.  This will only be computed
00602                              *   if the RSRepeatability bit in the parameters
00603                              *   is enabled (it costs too much time!).
00604                              */
00605       IdxScalePosStable,    /**< Scale stability defined as total
00606                              *   number of stable locations divided by
00607                              *   the total number of locations for
00608                              *   changes of scaling only.
00609                              */
00610       IdxRotationPosStable, /**< Rotation stability defined as
00611                              *   total number of stable locations
00612                              *   divided by the total number of
00613                              *   locations for changes in the rotation
00614                              *   only.
00615                              */
00616       IdxRSPosStable,       /**< Rotation stability defined as
00617                              *   total number of stable locations
00618                              *   divided by the total number of
00619                              *   locations for changes in the rotation
00620                              *   and scale. This will only be computed
00621                              *   if the RSStability bit in the parameters
00622                              *   is enabled (it costs too much time!).
00623                              */
00624       IdxScaleAStable,      /**< Scale angular stability defined as
00625                              *   total number of angular stable
00626                              *   locations divided by the total number
00627                              *   of locations for changes of scaling
00628                              *   only.
00629                              */
00630       IdxRotationAStable,   /**< Rotation angular stability defined
00631                              *   as total number of angular stable
00632                              *   locations divided by the total number
00633                              *   of locations for changes in the
00634                              *   rotation only.
00635                              */
00636       IdxRSAStable,         /**< Angular stability defined as total
00637                              *   number of angular stable locations
00638                              *   divided by the total number of
00639                              *   locations for changes in the rotation
00640                              *   and scale.  This will only be computed
00641                              *   if the RSStability bit in the parameters
00642                              *   is enabled (it costs too much time!).
00643                              */
00644     };
00645                   
00646 
00647 
00648     /**
00649      * Evaluate the set of images (in the parameters) using the
00650      * given parameterization.
00651      *
00652      * @param param parameters of the location selector to be used in
00653      *              the evaluation.
00654      * @param fitness multidimensional fitness measures for each image in
00655      *                one row.
00656      * @param onlyMeanAndVariance if true, the mean and variance of all
00657      *        results will be computed.  Otherwise all fitness measures
00658      *        for all images will be provided.
00659      */
00660     bool evaluate(const pyramidLocationSearch::parameters& param,
00661                   dmatrix& fitness,const bool onlyMeanAndVariance = false);
00662 
00663     /**
00664      * Evaluation of the location search with the given channel using
00665      * the given parameterization.
00666      */
00667     bool evaluate(const channel& chnl,
00668                   const pyramidLocationSearch::parameters& param,
00669                   dvector& fitness);
00670 
00671     //@}
00672 
00673   protected:
00674     /**
00675      * Total number of fitness measures that will be computed
00676      * 
00677      */
00678     static const int totalFitnessDimensionality;
00679 
00680     /**
00681      * Evaluation of the location search with the given channel
00682      * using the given parameterization.
00683      */
00684     bool evaluate(const channel& chnl,
00685                   const channel8& mask,
00686                   dvector& fitness);
00687 
00688     /**
00689      * Compare both location sets.
00690      *
00691      * @param olocs original image location set.
00692      * @param blocs back-transformed location set from the location extracted
00693      *              from the transformed image.
00694      * @param posStable number of locations stable respect their position
00695      * @param rotStable number of locations also stable in detected
00696      *                  rotation angle (rotStable <= posStable).
00697      * @return true if successful, false otherwise.
00698      */
00699     bool compare(const kdTree<tpoint<float>,int>& olocs,
00700                  const std::vector<location>& olocs,
00701                  const std::vector<location>& blocs,
00702                  int& posStable,
00703                  int& rotStable) const;
00704 
00705   private:
00706     /**
00707      * Structure containing a single enum with the number of bits required
00708      * for each parameter.
00709      */
00710     struct bits;
00711 
00712     /**
00713      * Functor used for the location search need only one setup for one
00714      * parameter set
00715      */
00716     pyramidLocationSearch locationSearcher;
00717 
00718     /**
00719      * Get the image name
00720      */
00721     std::string getMaskName(const std::string& imgName,
00722                             const std::string& postfix) const;
00723 
00724     /**
00725      * All channels read.
00726      *
00727      * Since the tests take a very long time, usually just a few images
00728      * are used here.  It is much better to read them once here.
00729      */
00730     std::vector<channel> imageData;
00731 
00732     /**
00733      * All mask for channels read.
00734      *
00735      * Since the tests take a very long time, usually just a few images
00736      * are used here.  It is much better to read them once and cache them here.
00737      *
00738      * The maskData contains the segmentation mask of the imageData, used to
00739      * optimize the selection of mask in the imporant regions.  If a
00740      * channel is empty, all locations will be valid.
00741      */
00742     std::vector<channel8> maskData;
00743 
00744   };
00745 }
00746 
00747 #endif
00748 

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