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

ltiKMColorQuantization.h

00001 /*
00002  * Copyright (C) 1999, 2000, 2001, 2002, 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 Digital Image/Signal Processing Library
00026  * file .......: ltiKMColorQuantization.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 30.04.99
00030  * revisions ..: $Id: ltiKMColorQuantization.h,v 1.11 2007/01/10 02:25:58 alvarado Exp $
00031  */
00032 
00033 #ifndef _LTI_KM_COLOR_QUANTIZATION_H_
00034 #define _LTI_KM_COLOR_QUANTIZATION_H_
00035 
00036 #include "ltiFunctor.h"
00037 #include "ltiImage.h"
00038 #include "ltiTypes.h"
00039 #include "ltiVector.h"
00040 #include "ltiColorQuantization.h"
00041 #include "ltiUniformDist.h"
00042 #include <map>
00043 
00044 namespace lti {
00045   /**
00046    * k-Means based color quantization.
00047    *
00048    * This functor calculates (using k-Means) an optimal color subpalette for
00049    * the input image.  The maximal number of colors to be used is given
00050    * through the parameters (inherited from colorQuantization::parameters).
00051    *
00052    * If the real number of colors used in the image is less than the desired
00053    * number of quantized colors, no quantization is done and the output palette
00054    * will contain all image colors, i.e. it will be smaller that the expected
00055    * size of parameters::numberOfColors.
00056    */
00057   class kMColorQuantization : public colorQuantization {
00058   public:
00059 
00060     /**
00061      * the parameters for the class kMColorQuantization
00062      */
00063     class parameters : public colorQuantization::parameters {
00064     public:
00065       /**
00066        * default constructor
00067        */
00068       parameters();
00069 
00070       /**
00071        * copy constructor
00072        * @param other the parameters object to be copied
00073        */
00074       parameters(const parameters& other);
00075 
00076       /**
00077        * destructor
00078        */
00079       ~parameters();
00080 
00081       /**
00082        * returns name of this type
00083        */
00084       const char* getTypeName() const;
00085 
00086       /**
00087        * copy the contents of a parameters object
00088        * @param other the parameters object to be copied
00089        * @return a reference to this parameters object
00090        */
00091       parameters& copy(const parameters& other);
00092 
00093       /**
00094        * copy the contents of a parameters object
00095        * @param other the parameters object to be copied
00096        * @return a reference to this parameters object
00097        */
00098       parameters& operator=(const parameters& other);
00099 
00100 
00101       /**
00102        * returns a pointer to a clone of the parameters
00103        */
00104       virtual functor::parameters* clone() const;
00105 
00106       /**
00107        * write the parameters in the given ioHandler
00108        * @param handler the ioHandler to be used
00109        * @param complete if true (the default) the enclosing begin/end will
00110        *        be also written, otherwise only the data block will be written.
00111        * @return true if write was successful
00112        */
00113       virtual bool write(ioHandler& handler,const bool complete=true) const;
00114 
00115       /**
00116        * write the parameters in the given ioHandler
00117        * @param handler the ioHandler to be used
00118        * @param complete if true (the default) the enclosing begin/end will
00119        *        be also written, otherwise only the data block will be written.
00120        * @return true if write was successful
00121        */
00122       virtual bool read(ioHandler& handler,const bool complete=true);
00123 
00124 #     ifdef _LTI_MSC_6
00125       /**
00126        * this function is required by MSVC only, as a workaround for a
00127        * very awful bug, which exists since MSVC V.4.0, and still by
00128        * V.6.0 with all bugfixes (so called "service packs") remains
00129        * there...  This method is also public due to another bug, so please
00130        * NEVER EVER call this method directly: use read() instead
00131        */
00132       bool readMS(ioHandler& handler,const bool complete=true);
00133 
00134       /**
00135        * this function is required by MSVC only, as a workaround for a
00136        * very awful bug, which exists since MSVC V.4.0, and still by
00137        * V.6.0 with all bugfixes (so called "service packs") remains
00138        * there...  This method is also public due to another bug, so please
00139        * NEVER EVER call this method directly: use write() instead
00140        */
00141       bool writeMS(ioHandler& handler,const bool complete=true) const;
00142 #     endif
00143 
00144       // ------------------------------------------------
00145       // the parameters
00146       // ------------------------------------------------
00147 
00148       /**
00149        * maximal number of iteration for the k-Means algorithm
00150        * (Default value: 50)
00151        */
00152       int maximalNumberOfIterations;
00153 
00154       /**
00155        * if "Palette-Changing" by iteration < thresholdDeltaPalette
00156        * than stop iterating
00157        * sum(distanceSqr(palNew-palOld))
00158        * (Default value: 0.2)
00159        */
00160       float thresholdDeltaPalette;
00161 
00162     };
00163 
00164     /**
00165      * default constructor
00166      */
00167     kMColorQuantization();
00168 
00169     /**
00170      * default constructor
00171      */
00172     kMColorQuantization(const parameters& par);
00173 
00174     /**
00175      * copy constructor
00176      */
00177     kMColorQuantization(const kMColorQuantization& other);
00178 
00179     /**
00180      * destructor
00181      */
00182     virtual ~kMColorQuantization();
00183 
00184     /**
00185      * returns current parameters.
00186      */
00187     const parameters& getParameters() const;
00188 
00189     /**
00190      * copy data of "other" functor.
00191      */
00192     kMColorQuantization& copy(const kMColorQuantization& other);
00193 
00194     /**
00195      * returns a pointer to a clone of the functor.
00196      */
00197     virtual functor* clone() const;
00198 
00199     /**
00200      * returns the name of this type
00201      */
00202     virtual const char* getTypeName() const;
00203 
00204     /**
00205      * Apply
00206      *
00207      * @param src original image with the true-color data
00208      * @param dest matrix<int> where the indexes of the calculated palette
00209      *             will be.
00210      * @param thePalette the color palette used by the matrix. If it is not
00211      *             empty, it will be taken as a InitPalette for
00212      *             the computation of the new one.
00213      * @return true if apply successful or false otherwise.
00214      */
00215     bool apply(const image& src,matrix<int>& dest,palette& thePalette) const;
00216 
00217     /**
00218      * Apply
00219      *
00220      * Operates on a copy of the given %parameters.
00221      * @param src original image with the true-color data
00222      * @param dest channel8 where the indexes of the also calculated palette
00223      *             will be.
00224      * @param thePalette the color palette used by the channel. If it is not
00225      *             empty, it will be taken as a InitPalette for
00226      *             the computation of the new one.
00227      * @return true if apply successful or false otherwise.
00228      */
00229     bool apply(const image& src,channel8& dest,palette& thePalette) const;
00230 
00231     /**
00232      * Operates on the given %parameter.
00233      *
00234      * @param srcdest image with the source data.  The result
00235      *                 will be left here too.
00236      * @return true if apply successful or false otherwise.
00237      */
00238     bool apply(image& srcdest) const;
00239 
00240     /**
00241      * Operates on the given %parameter.
00242      *
00243      * @param src image with the source data.
00244      * @param dest image with only the number of colors specified in
00245      *             the parameters
00246      * @return true if apply successful or false otherwise.
00247      */
00248     bool apply(const image& src,image& dest) const;
00249 
00250   private:
00251     /**
00252      * functor to calculate the kMeans
00253      */
00254     class kMeanColor {
00255     public:
00256       /**
00257        * constructor
00258        */
00259       kMeanColor(const int& maxNumOfClasses,
00260      const int& maxIterations,
00261      const float& thresdDeltaPal);
00262 
00263       /**
00264        * destructor
00265        */
00266       virtual ~kMeanColor();
00267 
00268       /**
00269        * calculate palette and colorMap using k-Means.
00270        * img is the input image, and it will be modified to use
00271        * the quantized colors!
00272        */
00273       bool operator() (const image& src,matrix<int>& dest,palette& thePalette);
00274 
00275     protected:
00276       /**
00277        * an entry of the hash table contains the number of pixels in
00278        * the image that have the color corresponding to this entry (counter)
00279        * and the index of this color in the cetroid-vector;
00280        */
00281       struct hashEntry {
00282         hashEntry(const int& idx=0,const int& cnt=0)
00283           : index(idx),counter(cnt) {};
00284         int index;
00285         int counter;
00286       };
00287 
00288       /**
00289        * each entry of the hash has this type
00290        */
00291       typedef std::map<int,hashEntry> hashMapType;
00292 
00293       /**
00294        * hash table type (see theHash for more details).
00295        */
00296       typedef hashMapType* hashType;
00297 
00298       /**
00299        * the centroids
00300        */
00301       vector<trgbPixel<float> > centroids;
00302 
00303       /**
00304        * centroid elements
00305        */
00306       vector<int> centerElems;
00307 
00308       /**
00309        * The hash table.
00310        *
00311        * The hash table contains all relevant information of the image to be
00312        * quantized, necessary for the k-Mean algorithms.
00313        *
00314        * It is organized as an array of 4096 (12 bits) hashMapType elements.
00315        *
00316        * This array is then accessed with the lower 12 bits of the color
00317        * value.  The upper 12 bits of the color are used to index the
00318        * proper map, that returns a hashEntry structure, with the correponding
00319        * centroid index for this color and the number of pixels assigned
00320        * to the centroid until now.
00321        *
00322        * In real world images, there will be an average between 5 and 10
00323        * elements per map.
00324        *
00325        * To access theHash directly, you can use the method at(), or put()
00326        */
00327       hashType theHash;
00328 
00329       /**
00330        * the maximal number of classes
00331        */
00332       const int maxNumberOfClasses;
00333 
00334       /**
00335        * the number of classes really used in the image
00336        */
00337       int realNumberOfClasses;
00338 
00339       /**
00340        * maximum number of iterations for the k-Means
00341        */
00342       const int maxNumberOfIterations;
00343 
00344       /**
00345        * if "Palette-Changing" by iteration < thresholdDeltaPalette
00346        * than stop iterating
00347        * sum(distanceSqr(palNew-palOld))
00348        */
00349       const float thresholdDeltaPalette;
00350 
00351       /**
00352        * returns a reference to the hash entry for the given pixel
00353        */
00354       inline hashEntry& at(const rgbPixel& px);
00355 
00356       /**
00357        * put the given pixel in the hash table (increments the counter if
00358        * already exists).
00359        * @return true if the pixel is new added, false otherwise.
00360        */
00361       inline bool put(const rgbPixel& px);
00362 
00363       /**
00364        * create and initialize the hash table with the image values
00365        */
00366       void initialize(const image& src);
00367 
00368       /**
00369        * get initial palette from hash
00370        */
00371       void getInitialPalette(const lti::palette& thePalette);
00372 
00373       /**
00374        * iterate to find the clusters
00375        */
00376       void iterate();
00377 
00378       /**
00379        * get a random color from the color hash
00380        */
00381       rgbPixel getAnImageColor();
00382 
00383       /**
00384        * size of the maps array
00385        */
00386       static const int firstKeySize;
00387 
00388       /**
00389        * a counter to generate the random colors
00390        */
00391       int lastHashPosition;
00392 
00393       /**
00394        * Random number generator
00395        */
00396       uniformDistribution uni;
00397     };
00398 
00399   };
00400 
00401 }
00402 
00403 #endif

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