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

ltiSegmentationEvaluation.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 .......: ltiSegmentationEvaluation.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 25.11.2003
00030  * revisions ..: $Id: ltiSegmentationEvaluation.h,v 1.1 2006/03/10 02:53:11 alvarado Exp $
00031  */
00032 
00033 #ifndef _LTI_SEGMENTATION_EVALUATION_TESTER_H_
00034 #define _LTI_SEGMENTATION_EVALUATION_TESTER_H_
00035 
00036 #include "ltiParetoFront.h"
00037 #include "ltiImage.h"
00038 
00039 namespace lti {
00040 
00041   /**
00042    * Pareto evaluation of segmentation functors.
00043    *
00044    * This abstract class provides a basic framework for the evaluation of
00045    * segmentation algorithms.  The functor evaluates a result comparing it
00046    * with some ground truth data, but it does not know anything about the
00047    * parameterization of any algorithm, which should be done by derived
00048    * classes.
00049    *
00050    * Several measures are provided to evaluate the algorithms:
00051    * - numberOfRegions
00052    * - numRegionsReciprocal (1/number of regions)
00053    * - pixelWisePotentialAccuracy
00054    * - objectWisePotentialAccuracy
00055    * - regionWiseInformationContent
00056    * - throughput
00057    * - regionIntegrity
00058    * - pixelWiseCertainty
00059    *
00060    * For the evaluation of a parameterization the algorithm takes all
00061    * images stored in the file specified in parameters::images.
00062    *
00063    * Following five methods have to be reimplemented in derived classes:
00064    *
00065    * For the pareto front interface
00066    * - chromosomeToPhenotype()
00067    * - phenotypeToChromosome()
00068    * - getChromosomeSize()
00069    *
00070    * For the real segmentation task
00071    * - init()
00072    * - segment() 
00073    * - getInstanceOfParam()
00074    *
00075    * In the parameters you should define two sets of values for minimum and
00076    * maximum tolerable values (usually called minValues and maxValues).  The
00077    * chromosomeToPhenotype method has to take care that the values produced 
00078    * lie in the corresponding intervals.
00079    *
00080    * The definition of the used fitness measures can be found in the paper:
00081    *
00082    * Mark Everingham, Henk Muller and Barry Thomas, 
00083    * "Evaluating Image Segmentation Algoritnms using the Pareto Front".
00084    * Proceedings of the 7th European Conference on Computer Vision,
00085    * 2002.
00086    *
00087    * except the region integrity and pixel-wise certainty, which are described
00088    * in
00089    *
00090    * Pablo Alvarado, "Segmentation of color images for interactive 3D 
00091    *                  object retrieval", Dissertation, Aachen, 2004.
00092    */
00093   class segmentationEvaluation : public paretoFront {
00094   public:
00095 
00096     /**
00097      * The parameters for the class segmentationEvaluation
00098      */
00099     class parameters : public paretoFront::parameters {
00100     public:
00101       /**
00102        * Default constructor
00103        */
00104       parameters();
00105 
00106       /**
00107        * Copy constructor
00108        * @param other the parameters object to be copied
00109        */
00110       parameters(const parameters& other);
00111 
00112       /**
00113        * Destructor
00114        */
00115       ~parameters();
00116 
00117       /**
00118        * Returns name of this type
00119        */
00120       const char* getTypeName() const;
00121 
00122       /**
00123        * Copy the contents of a parameters object
00124        * @param other the parameters object to be copied
00125        * @return a reference to this parameters object
00126        */
00127       parameters& copy(const parameters& other);
00128 
00129       /**
00130        * Copy the contents of a parameters object
00131        * @param other the parameters object to be copied
00132        * @return a reference to this parameters object
00133        */
00134       parameters& operator=(const parameters& other);
00135 
00136 
00137       /**
00138        * Returns a pointer to a clone of the parameters
00139        */
00140       virtual functor::parameters* clone() const;
00141 
00142       /**
00143        * Write the parameters in the given ioHandler
00144        * @param handler the ioHandler to be used
00145        * @param complete if true (the default) the enclosing begin/end will
00146        *        be also written, otherwise only the data block will be written.
00147        * @return true if write was successful
00148        */
00149       virtual bool write(ioHandler& handler,const bool& complete=true) const;
00150 
00151       /**
00152        * Read the parameters from the given ioHandler
00153        * @param handler the ioHandler to be used
00154        * @param complete if true (the default) the enclosing begin/end will
00155        *        be also written, otherwise only the data block will be written.
00156        * @return true if write was successful
00157        */
00158       virtual bool read(ioHandler& handler,const bool& complete=true);
00159 
00160 #     ifdef _LTI_MSC_6
00161       /**
00162        * This function is required by MSVC only, as a workaround for a
00163        * very awful bug, which exists since MSVC V.4.0, and still by
00164        * V.6.0 with all bugfixes (so called "service packs") remains
00165        * there...  This method is also public due to another bug, so please
00166        * NEVER EVER call this method directly: use read() instead
00167        */
00168       bool readMS(ioHandler& handler,const bool& complete=true);
00169 
00170       /**
00171        * This function is required by MSVC only, as a workaround for a
00172        * very awful bug, which exists since MSVC V.4.0, and still by
00173        * V.6.0 with all bugfixes (so called "service packs") remains
00174        * there...  This method is also public due to another bug, so please
00175        * NEVER EVER call this method directly: use write() instead
00176        */
00177       bool writeMS(ioHandler& handler,const bool& complete=true) const;
00178 #     endif
00179 
00180       // ------------------------------------------------
00181       // the parameters
00182       // ------------------------------------------------
00183 
00184       /**
00185        * @name Fitness measures
00186        *
00187        * Value containing the 1D fitness measures to be computed.
00188        * The constants defined here are:
00189        * - numberOfRegions
00190        * - numRegionsReciprocal (1/number of regions)
00191        * - pixelWisePotentialAccuracy
00192        * - objectWisePotentialAccuracy
00193        * - regionWiseInformationContent
00194        * - throughput (1/time)
00195        * - region integrity
00196        * - pixelWiseCertainty
00197        *
00198        * This sequence is important, since it determines the positions of
00199        * the single measures in the fitness output vector.
00200        *
00201        * If more fitness measures are selected than the inherited parameter
00202        * fitnessSpaceDimensionality, then the first ones in this sequence
00203        * will be selected.
00204        *
00205        * If less fitness measure are selected than the inherited parameter
00206        * fitnessSpaceDimensionality, then the rest of the vector will be
00207        * filled with zeros.
00208        */
00209       //@{
00210       /** 
00211        * Total number of regiong detected per image.
00212        *
00213        * This is usually a cost, and therefore you will never want to optimize
00214        * the number of regions as if it were a fitness, but, in some
00215        * applications, it may be necessary to search for the optimal
00216        * "over-segmentations", which will therefore use this as fitness.
00217        * 
00218        * Default value: false
00219        */
00220       bool numberOfRegions;
00221 
00222       /**
00223        * Reciprocal for the number of regions
00224        *
00225        * This is the inverse of the number of regions (1/number of regions).
00226        * Usually you want the get the less possible number of regions that
00227        * still don't merge different objects while partitioning an image.
00228        * 
00229        * This can be interpreted as the mean size of the regions normalized
00230        * to the size of the image.
00231        *
00232        * Default value: true
00233        */
00234       bool numRegionsReciprocal;
00235 
00236       /**
00237        * Pixel-wise potential accuracy.
00238        *
00239        * Describes the percentange of the image pixels than can be optimally
00240        * assigned to one of the ground-truth regions.
00241        *
00242        * This can be interpreted as a measure inversely proportional to the
00243        * degree of undersegmentation.
00244        *
00245        * Default value: true
00246        */
00247       bool pixelWisePotentialAccuracy;
00248       
00249       /**
00250        * Object-wise potential accuracy.
00251        *
00252        * Like pixel-wise potential accuracy but the contribution of each
00253        * reference region is normalized to its size so that all regions in
00254        * the reference segmentation are equally important.
00255        *
00256        * Default value: false
00257        */
00258       bool objectWisePotentialAccuracy;
00259 
00260       /**
00261        * Region-wise information content.
00262        *
00263        * Proportion of the reference region covered by each single region.
00264        *
00265        * Default value: false
00266        */
00267       bool regionWiseInformationContent;
00268 
00269       /**
00270        * Throughput
00271        *
00272        * Number of images segmented per second.
00273        *
00274        * Default value: false
00275        */
00276       bool throughput; 
00277 
00278       /**
00279        * Region integrity
00280        *
00281        * Measures the number of regions mapped to a reference region.  The
00282        * function used punishes over- and under-segmentation.
00283        * 
00284        * Default value: false
00285        */
00286       bool regionIntegrity;
00287 
00288       /**
00289        * Pixel-wise certainty
00290        *
00291        * This makes only sense for some segmentation functors, that can deliver
00292        * the certainty with which a pixel was assigned to a label.
00293        *
00294        * Default value: false
00295        */
00296       bool pixelWiseCertainty;
00297       //@}
00298 
00299       /**
00300        * Name of a file containing all images to be analyzed.
00301        *
00302        * Default value: "images.txt"
00303        */
00304       std::string images;
00305 
00306       /**
00307        * Mask postfix
00308        *
00309        * For each image file in \a images, a manual segmented mask is required
00310        * as "ground truth".
00311        *
00312        * The filename of the masks will be assumed to be the same
00313        * image name with the given postfix.  For example, if an image is
00314        * called "test.png" and the postfix is "-preseg", then the
00315        * mask will be assumed to be "test-preseg.png".
00316        *
00317        * Default value: "_premask"
00318        */
00319       std::string goldenPostfix;
00320 
00321       /**
00322        * Previous Mask Postfix.
00323        *
00324        * To save evaluation time, the test of higher-level algorithm can load
00325        * the lower-level segmentations of the images in a file with this
00326        * postfix and type lti (see lti::ltiFunctor), which is the only format
00327        * that can save imatrices.  For example, if an image is called
00328        * "test.png" and the prevStagePostfix is "-ibs", then the mask will
00329        * be assumed to be in "test-ibs.lti".
00330        *
00331        * If no file is found with these names, then a low-level segmentation 
00332        * will be assumed, which does not require any previous masks.
00333        *
00334        * Default value: "_ibs" 
00335        */
00336       std::string prevStagePostfix;
00337 
00338       /**
00339        * @name Fitness parameterizations
00340        */
00341       //@{
00342       /**
00343        * Minimal size for valid region
00344        *
00345        * Percentage of the image size that defines the minimal size of a
00346        * region to be considered in the statistics for region-wise information
00347        * content and object-wise potential accuracy.
00348        *
00349        * This value must be between 0 and 1.
00350        *
00351        * Default: 0.0005 (i.e. 0.05%)
00352        */
00353       float minValidRegionSize;
00354       //@}
00355     };
00356 
00357     /**
00358      * Default constructor
00359      */
00360     segmentationEvaluation();
00361 
00362     /**
00363      * Construct a functor using the given parameters
00364      */
00365     segmentationEvaluation(const parameters& par);
00366 
00367     /**
00368      * Copy constructor
00369      * @param other the object to be copied
00370      */
00371     segmentationEvaluation(const segmentationEvaluation& other);
00372 
00373     /**
00374      * Destructor
00375      */
00376     virtual ~segmentationEvaluation();
00377 
00378     /**
00379      * Returns the name of this type ("segmentationEvaluation")
00380      */
00381     virtual const char* getTypeName() const;
00382 
00383     /**
00384      * Returns used parameters
00385      */
00386     const parameters& getParameters() const;
00387 
00388     /**
00389      * Set the parameters
00390      */
00391     bool setParameters(const functor::parameters& other);
00392 
00393     /**
00394      * @name Public methods to be reimplemented
00395      */
00396     //@{
00397 
00398     /**
00399      * Convert a binary-chain representation of a chromosome to a valid
00400      * parameter object.
00401      */
00402     virtual bool chromosomeToPhenotype(const chromosome& genotype,
00403                                       functor::parameters& phenotype) const=0;
00404 
00405     /**
00406      * Return a fresh allocated parameters for the evaluated functor, which is
00407      * equivalent to the given genotype.
00408      */
00409     virtual functor::parameters* 
00410     chromosomeToPhenotype(const chromosome& genotype) const;
00411 
00412     /**
00413      * Evaluate Chromosome
00414      *
00415      * This method is one of the most important ones for the pareto evaluation.
00416      * Its task is to produce a multidimensional fitness measure for a given
00417      * chromosome.
00418      *
00419      * It returns true if the evaluation was successful, of false if the
00420      * phenotype represents some invalid parameterization.  It is highly 
00421      * recomended that the mutation and crossover methods are reimplemented to 
00422      * avoid invalid parameterizations.
00423      */
00424     virtual bool evaluateChromosome(const chromosome& individual,
00425                                     dvector& fitness); 
00426 
00427     //@}
00428 
00429     /**
00430      * @name Evaluation Functions
00431      *
00432      * The real evaluation is provided here in order to compute measures
00433      * independently of the Pareto Front.
00434      */
00435     //@{
00436     /**
00437      * Index names for the complete multidimensional fitness measure
00438      */
00439     enum {
00440       IdxNumRegions,        /**< Mean number of regions.                   */
00441       IdxNumRegionsRecip,   /**< Reciprocal of the mean number of regions. */
00442       IdxPixelAccuracy,     /**< Pixel wise potential accuracy.            */
00443       IdxObjectAccuracy,    /**< Object wise potential accuracy.           */
00444       IdxRegionWiseInfo,    /**< Region wise information content.          */
00445       IdxThroughput,        /**< 1.0/time in s^-1, meaning the number of
00446                              *   complete segmentations per second.
00447                              */
00448       IdxRegionIntegrity,   /**< Region integrity                          */
00449       IdxPixelCertainty     /**< Pixel-wise certainty                      */
00450     };
00451 
00452     /**
00453      * Evaluate the set of images (in the parameters) using the
00454      * given parameterization.
00455      *
00456      * @param param parameters for the segmentation functor to be used in the
00457      *              evaluation.
00458      * @param fitness multidimensional fitness measures for all images
00459      */
00460     bool evaluate(const functor::parameters& param,dvector& fitness);
00461 
00462     /**
00463      * Evaluation of the segmentation with the given channel using
00464      * the given parameterization.
00465      *
00466      * The real measures for the single image are obtained with the
00467      * element-wise division between fitness and norm.  But if several images
00468      * are used in the computations, the norms of each image have to be added
00469      * first.
00470      *
00471      * It is assumed that there is no previous stage (empty previous stage
00472      * mask).
00473      */
00474     virtual bool evaluate(const image& img,
00475                           const channel8& mask,
00476                           const functor::parameters& param,
00477                           dvector& fitness,
00478                           dvector& norm);
00479 
00480     /**
00481      * Evaluation of the segmentation with the given channel using
00482      * the given parameterization.
00483      *
00484      * The real measures for the single image are obtained with the
00485      * element-wise division between fitness and norm.  But if several images
00486      * are used in the computations, the norms of each image have to be added
00487      * first.
00488      */
00489     virtual bool evaluate(const image& img,
00490                           const imatrix& prevStage,
00491                           const channel8& mask,
00492                           const functor::parameters& param,
00493                           dvector& fitness,
00494                           dvector& norm);
00495 
00496     /**
00497      * Evaluation of the segmentation with the given channel using
00498      * a previously set parameterization.
00499      *
00500      * The real measures for the single image are obtained with the
00501      * element-wise division between fitness and norm.  But if several images
00502      * are used in the computations, the norms of each image have to be added
00503      * first.
00504      */
00505     virtual bool evaluate(const image& img,
00506                           const imatrix& prevStage,
00507                           const channel8& mask,
00508                           dvector& fitness,
00509                           dvector& norm);
00510 
00511     /**
00512      * Evaluation of segmentation
00513      *
00514      * Since you give already the results in this method, it is not possible to
00515      * compute the throughput and certainty measures.
00516      */
00517     virtual bool evaluate(const imatrix& result,
00518                           const channel8& refMask,
00519                           dvector& fitness,
00520                           dvector& norm,
00521                           const float minValidRegionSize=0.0005);
00522                           
00523 
00524     //@}
00525 
00526   protected:
00527     /**
00528      * Total number of fitness measures that will be computed
00529      * 
00530      */
00531     static const int totalFitnessDimensionality;
00532 
00533     /**
00534      * Cache for the images
00535      */
00536     std::vector<image> imageData;
00537 
00538     /**
00539      * Cache for the presegmentation masks
00540      */
00541     std::vector<channel8> maskData;
00542 
00543     /**
00544      * Cache for the previous stage masks
00545      */
00546     std::vector<imatrix> prevMaskData;
00547 
00548     /**
00549      * File names of the reference data
00550      */
00551     std::vector<std::string> goldenNames;
00552 
00553     /**
00554      * Read images and masks
00555      */
00556     bool readData();
00557 
00558     /**
00559      * Get the image name
00560      */
00561     std::string getMaskName(const std::string& imgName,
00562                             const std::string& postfix) const;
00563 
00564     /**
00565      * Get the image name of the previous stage file
00566      */
00567     std::string getPrevName(const std::string& imgName,
00568                             const std::string& postfix) const;
00569 
00570     /**
00571      * @name The segmentation evaluation methods
00572      */
00573     //@{
00574     /**
00575      * Initialize the segmentation functor
00576      */
00577     virtual bool init(const functor::parameters& param) = 0;
00578 
00579     /**
00580      * Segmentate an image using the parameterization set with init()
00581      *
00582      * @param img image to be segmented
00583      * @param prevStage segmentation mask from a previous stage.  Image-based
00584      *                  segmentation algorithms ignore this argument (in a
00585      *                  strict sense they consider a mask in which each pixel
00586      *                  has its own label).
00587      * @param mask new segmentation labeled mask.
00588      * @param certainty the certainty, with which the algorithm assigns each
00589      *                  pixel to its label.  If an algorithm does not provide
00590      *                  such measure (like almost all image-based algorithms)
00591      *                  this value will be empty, and for the computations
00592      *                  it will be assumed that all pixels have a certainty of
00593      *                  1.0 to be what they are.
00594      *
00595      * @return true if successful, false otherwise.
00596      */
00597     virtual bool segment(const image& img,
00598                          const imatrix& prevStage,
00599                          imatrix& mask,
00600                          channel& certainty) = 0;
00601 
00602     //@}
00603 
00604     /**
00605      * Return a new object with the correct parameters' type
00606      */
00607     virtual functor::parameters* getInstanceOfParam() const = 0;
00608 
00609     /**
00610      * Empty matrix used everywhere.
00611      */
00612     static const imatrix emptyMatrix;
00613 
00614 
00615   };
00616 }
00617 
00618 #endif
00619 

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