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

ltiColorACASegmentation.h

00001 /*
00002  * Copyright (C) 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 .......: ltiColorACASegmentation.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 6.1.2004
00030  * revisions ..: $Id: ltiColorACASegmentation.h,v 1.4 2006/02/07 18:37:27 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_COLOR_A_C_A_SEGMENTATION_H_
00034 #define _LTI_COLOR_A_C_A_SEGMENTATION_H_
00035 
00036 #include "ltiImage.h"
00037 #include "ltiSegmentation.h"
00038 #include "ltiKMColorQuantization.h"
00039 
00040 #include <vector>
00041 
00042 namespace lti {
00043   /**
00044    * Color Adaptive Clustering Algorithm.
00045    *
00046    * This functor provides a segmentation algorithm based on the Adaptive
00047    * Clustering Algorithm (ACA) proposed by Thrasyvoulos N. Pappas in
00048    * his paper "An adaptive clustering algorithm for image segmentation",
00049    * IEEE Transactions on signal processing, vol. 40, No. 4, april 1992.
00050    *
00051    * Even if in the original version the algorithm has been applied to
00052    * gray valued images, the current implementation has been adapted for the
00053    * segmentation of color images.
00054    * 
00055    * The algorithm first generates an image pyramid for the input.  For the
00056    * smallest image a k-Means color clustering is done, and a labeling 
00057    * procedure assigns to each pixel the corresponding label.
00058    * 
00059    * Using this first segmentation proposal and the current window
00060    * size (initially the whole image) it generates a new estimation of the
00061    * expected mean values for each pixel.  With the new mean values compute the
00062    * a-posteriori probabilities for each pixel to belong to any of the classes
00063    * and compute with them a new segmentation hypothesis.
00064    *
00065    * Repeat the estimation of the expected values and the new
00066    * segmentation until the algorithm converges or only a small number
00067    * of changes has been done in the last iteration.
00068    *
00069    * Reduce the window size and begin the iterations again, until the minimum
00070    * window size is reached.
00071    *
00072    * Now duplicate the size of the segmentation result and use it as
00073    * initialization for the next iteration using the next pyramid
00074    * level.
00075    * 
00076    * The whole process is repeated until the highest resolution level has 
00077    * been analyzed. 
00078    *
00079    * Note that this algorithm is very slow.  It is implemented to
00080    * provide a comparison possibility with your own algorithms.
00081    *
00082    */
00083   class colorACASegmentation : public segmentation {
00084   public:
00085     /**
00086      * The parameters for the class colorACASegmentation
00087      */
00088     class parameters : public segmentation::parameters {
00089     public:
00090       /**
00091        * Default constructor
00092        */
00093       parameters();
00094 
00095       /**
00096        * Copy constructor
00097        * @param other the parameters object to be copied
00098        */
00099       parameters(const parameters& other);
00100 
00101       /**
00102        * Destructor
00103        */
00104       ~parameters();
00105 
00106       /**
00107        * Returns name of this type
00108        */
00109       const char* getTypeName() const;
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& copy(const parameters& other);
00117 
00118       /**
00119        * Copy the contents of a parameters object
00120        * @param other the parameters object to be copied
00121        * @return a reference to this parameters object
00122        */
00123       parameters& operator=(const parameters& other);
00124 
00125 
00126       /**
00127        * Returns a pointer to a clone of the parameters
00128        */
00129       virtual functor::parameters* clone() const;
00130 
00131       /**
00132        * Write the parameters in 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 write(ioHandler& handler,const bool complete=true) const;
00139 
00140       /**
00141        * Read the parameters from the given ioHandler
00142        * @param handler the ioHandler to be used
00143        * @param complete if true (the default) the enclosing begin/end will
00144        *        be also written, otherwise only the data block will be written.
00145        * @return true if write was successful
00146        */
00147       virtual bool read(ioHandler& handler,const bool complete=true);
00148 
00149 #     ifdef _LTI_MSC_6
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 read() instead
00156        */
00157       bool readMS(ioHandler& handler,const bool complete=true);
00158 
00159       /**
00160        * This function is required by MSVC only, as a workaround for a
00161        * very awful bug, which exists since MSVC V.4.0, and still by
00162        * V.6.0 with all bugfixes (so called "service packs") remains
00163        * there...  This method is also public due to another bug, so please
00164        * NEVER EVER call this method directly: use write() instead
00165        */
00166       bool writeMS(ioHandler& handler,const bool complete=true) const;
00167 #     endif
00168 
00169       // ------------------------------------------------
00170       // the parameters
00171       // ------------------------------------------------
00172 
00173       /**
00174        * Number of levels in the pyramid.
00175        *
00176        * This value \b must be greater or equal one.
00177        *
00178        * Default value: 4
00179        */
00180       int levels;
00181 
00182       /**
00183        * Parameters for the kMeans quantization.
00184        *
00185        * The number of means used in the whole algorithm will be given by
00186        * the attribute kMColorQuantization::parameters::numberOfColors.
00187        *
00188        * Default value: all default values except numberOfColors, which is set
00189        *                to 16.
00190        */
00191       kMColorQuantization::parameters kMeansParam;
00192 
00193       /**
00194        * Beta factor used in the Gibbs distribution model for the spatial
00195        * consideration.
00196        *
00197        * Default value: 0.5
00198        */
00199       float beta;
00200 
00201       /**
00202        * A-Priori label membership.
00203        * 
00204        * If empty, all labels are equiprobable.  If not empty, for those labels
00205        * with an entry, this corresponds to the one-pixel clique potentials.
00206        *
00207        * Default value: empty vector
00208        */
00209       fvector alpha;
00210 
00211       /**
00212        * Standard deviation of Gaussian white distribution assumed for the
00213        * region noise.
00214        *
00215        * Since the value range of the data is between 0 and 255, you can 
00216        * consider this value as the deviation brightness expected in each
00217        * of the R,G and B color channels.
00218        *
00219        * Default value: 5
00220        */
00221       float sigma;
00222 
00223       /**
00224        * Convergence criterion for a \e cycle.
00225        *
00226        * After the mean values has been estimated, the new segmentation has
00227        * to be computed using an iterative procedure that uses the previous
00228        * segmentation as suggestion and continues until less than the given
00229        * percentage of totall image pixels change.
00230        *
00231        * Note that this value is usually much smaller than one.
00232        *
00233        * Default value: 0.0004f
00234        */
00235       float convergenceCriterion;
00236 
00237       /**
00238        * Threshold minimum.
00239        *
00240        * The real threshold is computed multiplying this value by the current
00241        * window width.
00242        *
00243        * If the number of pixels in a window that belong to the current label
00244        * is less than the computed threshold, the current pixel is marked as
00245        * undefined and the desition to which level it will belong will be made
00246        * according to spatial conditiions only (based on a MRF).
00247        *
00248        * Default value: 1.0
00249        */
00250       float tMin;
00251 
00252       /**
00253        * Maximum number of iterations with the same window size
00254        *
00255        * This parameter controls how much iteration will be done with the
00256        * same window size of mean-estimation + segmentation-estimation steps.
00257        *
00258        * Default value: 20
00259        */
00260       int nMax;
00261 
00262       /**
00263        * The positioning of the window centroids will be computing
00264        * using this overlap factor.  If zero is given, the windows
00265        * will be place side by side.  If one is given the windows will be
00266        * computed for each pixel in the image, which is very expensive.
00267        *
00268        * Pappas suggests the use of 0.5f.
00269        *
00270        * Default value: 0.5f
00271        */
00272       float windowOverlap;
00273 
00274       /**
00275        * Initial window size as percentage of the minimum of the image
00276        * dimensions.
00277        *
00278        * Default value: 1.0f
00279        */
00280       float firstWindowSize;
00281 
00282       /**
00283        * Absolute minimum window size.
00284        *
00285        * The window size will be reduce until it is smaller that this size.
00286        *
00287        * Default value: 7
00288        */
00289       int lastWindowSize;
00290 
00291       /**
00292        * Multiplicative window size step change.
00293        *
00294        * This values must be possitive and strictly smaller than one.
00295        *
00296        * If you set the value outsize this range, no window iteration sizes
00297        * will be done, and the algorithm will behave like a k-Means clustering
00298        * (but very slow).
00299        *
00300        * Default value 0.5
00301        */
00302       float windowSizeStep;
00303 
00304     };
00305 
00306     /**
00307      * Default constructor
00308      */
00309     colorACASegmentation();
00310 
00311     /**
00312      * Construct a functor using the given parameters
00313      */
00314     colorACASegmentation(const parameters& par);
00315 
00316     /**
00317      * Copy constructor
00318      * @param other the object to be copied
00319      */
00320     colorACASegmentation(const colorACASegmentation& other);
00321 
00322     /**
00323      * Destructor
00324      */
00325     virtual ~colorACASegmentation();
00326 
00327     /**
00328      * Returns the name of this type ("colorACASegmentation")
00329      */
00330     virtual const char* getTypeName() const;
00331 
00332     /**
00333      * Segmentates the \a srcdest image and replaces it with the 
00334      * estimated mean values.
00335      *
00336      * @param srcdest image with the source data.  The result
00337      *                 will be left here too.
00338      * @return true if apply successful or false otherwise.
00339      */
00340     bool apply(image& srcdest) const;
00341 
00342     /**
00343      * Segmentates the image \a src and compute the estimated mean
00344      * values.
00345      *
00346      * @param src image with the source data.
00347      * @param dest image with the smooth changing means per region.
00348      * @return true if apply successful or false otherwise.
00349      */
00350     bool apply(const image& src,image& dest) const;
00351 
00352     /**
00353      * Segmentates the image and computes the labeled mask, with labels between
00354      * 0 and parameters::kMeansParam::numberOfColors - 1.  Additionally, the
00355      * estimated mean values will be computed.
00356      *
00357      * Note that the result differs from other segmentation approaches in the
00358      * fact that the functor doesn't compute a palette, since the values within
00359      * a region are allowed to slowly change.
00360      *
00361      * @param src image with the source data
00362      * @param mask imatrix with the labels for each region
00363      * @param means image with the estimated mean values per pixel.
00364      */
00365     bool apply(const image& src,imatrix& mask,image& means) const;
00366 
00367     /**
00368      * Segmentates the image and computes the labeled mask, with labels between
00369      * 0 and parameters::kMeansParam::numberOfColors - 1.  Additionally, the
00370      * estimated mean values will be computed.
00371      *
00372      * Note that the result differs from other segmentation approaches in the
00373      * fact that the functor doesn't compute a palette, since the values within
00374      * a region are allowed to slowly change.
00375      *
00376      * @param src image with the source data
00377      * @param mask imatrix with the labels for each region
00378      */
00379     bool apply(const image& src,imatrix& mask) const;
00380 
00381     /**
00382      * Copy data of "other" functor.
00383      * @param other the functor to be copied
00384      * @return a reference to this functor object
00385      */
00386     colorACASegmentation& copy(const colorACASegmentation& other);
00387 
00388     /**
00389      * Alias for copy member
00390      * @param other the functor to be copied
00391      * @return a reference to this functor object
00392      */
00393     colorACASegmentation& operator=(const colorACASegmentation& other);
00394 
00395     /**
00396      * Returns a pointer to a clone of this functor.
00397      */
00398     virtual functor* clone() const;
00399 
00400     /**
00401      * Returns used parameters
00402      */
00403     const parameters& getParameters() const;
00404 
00405     /**
00406      * Set the parameters
00407      */
00408     bool setParameters(const functor::parameters& param);
00409 
00410   protected:
00411     /**
00412      * Segmentates the image and computes the labeled mask, with labels between
00413      * 0 and parameters::kMeansParam::numberOfColors - 1.  Additionally, the
00414      * estimated mean values will be computed.
00415      *
00416      * Note that the result differs from other segmentation approaches in the
00417      * fact that the functor doesn't compute a palette, since the values within
00418      * a region are allowed to slowly change.
00419      *
00420      * @param src image with the source data
00421      * @param mask imatrix with the labels for each region
00422      * @param means image with the estimated mean values per pixel.
00423      * @param computeMeans compute image with means
00424      * @return true if successful, false otherwise.
00425      */
00426     bool aca(const image& src,imatrix& mask,image& means,
00427              const bool computeMeans) const;
00428 
00429     /**
00430      * Initialize the segmentation using k-Means.  
00431      *
00432      * The argument \a mask represents the variable \a x in the original paper
00433      */
00434     bool kMeansInit(const image& src, imatrix& mask) const;
00435 
00436     /**
00437      * Estimates the means channel using linear interpolation of the support
00438      * points at the grid, using a window of the given size.
00439      *
00440      * The means image vector must have the proper size when initialized:
00441      * parameters::kMeansParam::numberOfColors
00442      */
00443     bool estimateMeans(const image& src,
00444                        const imatrix& mask,
00445                        std::vector<image>& means,
00446                        const int windowSize,
00447                        const int gridSize,
00448                        const int tMin) const;
00449 
00450     /**
00451      * Interpolate all pixels not at the grid points using bilinear
00452      * interpolation.
00453      */
00454     bool interpolate(image& src,
00455                      const int gridSize) const;
00456 
00457     /**
00458      * Estimate segmentation given the means
00459      */
00460     bool estimateSegmentation(const image& src,
00461                               const std::vector<image>& means,
00462                               const float gfactor,
00463                               imatrix& mask,
00464                               int& cycles) const;
00465 
00466     /**
00467      * Compute label.
00468      *
00469      * @param src original image
00470      * @param means the mean values for each label
00471      * @param mask initial segmentation 
00472      * @param p point to be evaluated
00473      * @param from which neighbor should be considered first
00474      * @param to which neighbor should be considered last
00475      * @param gfactor must be -1/2*sigma^2
00476      * @param numChanges number of changes taken in the iteration.
00477      * @return label that maximizes the a posteriori probability
00478      */
00479     inline int computeLabel(const image& src,
00480                             const std::vector<image>& means,
00481                             const imatrix& mask,
00482                             const point& p,
00483                             const int from,
00484                             const int to,
00485                             const float gfactor,
00486                             int& numChanges) const;
00487     /**
00488      * Estimate segmentation given the means
00489      */
00490     bool estimateSegmentationStep(const image& src,
00491                                   const std::vector<image>& means,
00492                                   const float gfactor,
00493                                   imatrix& mask,
00494                                   imatrix& nmask,
00495                                   int& numChanges) const;
00496 
00497     /**
00498      * Create an image containing the appropriate mean values
00499      */
00500     bool createMeanImage(const std::vector<image>& lmeans,
00501                          const imatrix mask,
00502                          image& means) const;
00503 
00504   private:
00505     /**
00506      * Constants
00507      *
00508      * One point clique constants.  This has always a length numberOfColors 
00509      */
00510     fvector alpha;
00511 
00512     /**
00513      * Constant 
00514      *
00515      * Potential for the two-point cliques.
00516      */
00517     float beta;
00518 
00519   };
00520 }
00521 
00522 #endif

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