CVR-Lib last update 20 Sep 2009

cvrKMColorQuantization.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 /**
00042  * \file   cvrKMColorQuantization.h
00043  *         Contains a class for color quantization using the k-Means algorithm.
00044  * \author Pablo Alvarado
00045  * \date   30.04.1999 (CVR-Lib 1)
00046  * \date   12.01.2006 (CVR-Lib )
00047  *
00048  * $Id: cvrKMColorQuantization.h,v 1.2 2006/01/15 22:15:27 alvarado Exp $
00049  */
00050 
00051 
00052 #ifndef _CVR_KM_COLOR_QUANTIZATION_H_
00053 #define _CVR_KM_COLOR_QUANTIZATION_H_
00054 
00055 #include "cvrFunctor.h"
00056 #include "cvrImage.h"
00057 #include "cvrTypes.h"
00058 #include "cvrVector.h"
00059 #include "cvrColorQuantization.h"
00060 #include "cvrRGBPixel.h"
00061 #include <map>
00062 
00063 namespace cvr {
00064   /**
00065    * k-Means based color quantization.
00066    *
00067    * This functor calculates (using k-Means) an optimal color subpalette for
00068    * the input image.  The maximal number of colors to be used is given
00069    * through the parameters (inherited from colorQuantization::parameters).
00070    *
00071    * If the real number of colors used in the image is less than the desired
00072    * number of quantized colors, no quantization is done and the output palette
00073    * will contain all image colors, i.e. it will be smaller that the expected
00074    * size of parameters::numberOfColors.
00075    *
00076    * @ingroup gColorQuantization
00077    */
00078   class kMColorQuantization : public colorQuantization {
00079   public:
00080 
00081     /**
00082      * the parameters for the class kMColorQuantization
00083      */
00084     class parameters : public colorQuantization::parameters {
00085     public:
00086       /**
00087        * default constructor
00088        */
00089       parameters();
00090 
00091       /**
00092        * copy constructor
00093        * @param other the parameters object to be copied
00094        */
00095       parameters(const parameters& other);
00096 
00097       /**
00098        * destructor
00099        */
00100       ~parameters();
00101 
00102 
00103       /**
00104        * Returns the name of this type
00105        */
00106       virtual const std::string& name() const;
00107 
00108       /**
00109        * Returns a pointer to a clone of the parameters
00110        */
00111       virtual parameters* clone() const;
00112 
00113       /**
00114        * Returns a pointer to a new instance of the parameters
00115        */
00116       virtual parameters* newInstance() const;
00117 
00118       /**
00119        * Copy the other instance.here.
00120        */
00121       parameters& copy(const parameters& other);
00122 
00123       /**
00124        * Copy the contents of a parameters object.
00125        *
00126        * @param other the parameters object to be copied
00127        * @return a reference to this parameters object
00128        */
00129       parameters& operator=(const parameters& other);
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        * write the parameters in 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       // ------------------------------------------------
00150       // the parameters
00151       // ------------------------------------------------
00152 
00153       /**
00154        * Maximal number of iterations taken for the k-Means algorithm to
00155        * converge.
00156        *
00157        * Default value: 50
00158        */
00159       int maximalNumberOfIterations;
00160 
00161       /**
00162        * Smallest change of palette.
00163        *
00164        * If the difference between the palette in the previous iteration
00165        * and the palette in the current iteration is smaller than this value
00166        * then it will be assumed that the algorithm has converged.
00167        *
00168        * The difference is computed as the sum of the distances between
00169        * corresponding entries of the palette, taken in the RGB color space,
00170        * with an L2 distance, i.e. sum(distanceSqr(palNew-palOld)).
00171        *
00172        * Note that the axes of the RGB space are dimensioned from 0 to 255.
00173        *
00174        * Default value: 0.2
00175        */
00176       float thresholdDeltaPalette;
00177 
00178     };
00179 
00180     /**
00181      * Default constructor
00182      */
00183     kMColorQuantization();
00184 
00185     /**
00186      * Constructor with parameters
00187      */
00188     kMColorQuantization(const parameters& par);
00189 
00190     /**
00191      * Copy constructor
00192      */
00193     kMColorQuantization(const kMColorQuantization& other);
00194 
00195     /**
00196      * Destructor
00197      */
00198     virtual ~kMColorQuantization();
00199 
00200     /**
00201      * Returns current parameters.
00202      */
00203     const parameters& getParameters() const;
00204 
00205     /**
00206      * Returns the name of this type.
00207      */
00208     virtual const std::string& name() const;
00209 
00210     /**
00211      * Copy data of "other" functor.
00212      *
00213      * @param other the functor to be copied
00214      * @return a reference to this functor object
00215      */
00216     kMColorQuantization& copy(const kMColorQuantization& other);
00217 
00218     /**
00219      * Returns a pointer to a clone of this functor.
00220      */
00221     virtual kMColorQuantization* clone() const;
00222 
00223     /**
00224      * Returns a pointer to a clone of this functor.
00225      */
00226     virtual kMColorQuantization* newInstance() const;
00227 
00228 
00229     /**
00230      * Quantize the colors of src and leave the labels for the quantized colors
00231      * in dest, and in the palette entries corresponding to the labels the
00232      * mean colors for each label.
00233      *
00234      * @param src Original image with the true-color data
00235      * @param dest channel8 where the indexes of the also calculated palette
00236      *             will be.
00237      * @param thePalette the color palette used by the channel. If it is not
00238      *             empty, it will be taken as a InitPalette for
00239      *             the computation of the new one.
00240      * @return true if apply successful or false otherwise.
00241      */
00242     virtual bool apply(const image& src,
00243                              matrix<ubyte>& dest,
00244                              palette& thePalette) const;
00245 
00246 
00247     /**
00248      * Quantize the colors of src and leave the labels for the quantized colors
00249      * in dest, and in the palette entries corresponding to the labels the
00250      * mean colors for each label.
00251      *
00252      * @param src Original image with the true-color data
00253      * @param dest matrix<int> where the indexes of the calculated palette
00254      *             will be.
00255      * @param thePalette The color palette used by the matrix. If it is not
00256      *             empty, it will be taken as a InitPalette for
00257      *             the computation of the new one.
00258      * @return true if apply successful or false otherwise.
00259      */
00260     virtual bool apply(const image& src,
00261                              matrix<int>& dest,
00262                              palette& thePalette) const;
00263 
00264 
00265     /**
00266      * Quantize the colors of the given image.
00267      *
00268      * @param srcdest image with the source data.  The result
00269      *                 will be left here too.
00270      * @return true if apply successful or false otherwise.
00271      */
00272     virtual bool apply(image& srcdest) const;
00273 
00274     /**
00275      * Quantize the colors of the given src image and leave the result in dest.
00276      *
00277      * @param src image with the source data.
00278      * @param dest image with only the number of colors specified in
00279      *             the parameters
00280      * @return true if apply successful or false otherwise.
00281      */
00282     virtual bool apply(const image& src,image& dest) const;
00283 
00284   private:
00285     /**
00286      * functor to calculate the kMeans
00287      */
00288     class kMeanColor {
00289     public:
00290       /**
00291        * constructor
00292        */
00293       kMeanColor(const int& maxNumOfClasses,
00294      const int& maxIterations,
00295      const float& thresdDeltaPal);
00296 
00297       /**
00298        * destructor
00299        */
00300       virtual ~kMeanColor();
00301 
00302       /**
00303        * calculate palette and colorMap using k-Means.
00304        * img is the input image, and it will be modified to use
00305        * the quantized colors!
00306        */
00307       bool operator()(const image& src,matrix<int>& dest,palette& thePalette);
00308 
00309     protected:
00310       /**
00311        * An entry of the hash table contains the number of pixels in
00312        * the image that have the color corresponding to this entry (counter)
00313        * and the index of this color in the cetroid-vector;
00314        */
00315       struct hashEntry {
00316         hashEntry(const int& idx=0,const int& cnt=0)
00317           : index(idx),counter(cnt) {};
00318         int index;
00319         int counter;
00320       };
00321 
00322       /**
00323        * Each entry of the hash has this type
00324        */
00325       typedef std::map<int,hashEntry> hashMapType;
00326 
00327       /**
00328        * Hash table type (see theHash for more details).
00329        */
00330       typedef hashMapType* hashType;
00331 
00332       /**
00333        * the centroids
00334        */
00335       vector< frgbPixel > centroids_;
00336 
00337       /**
00338        * centroid elements
00339        */
00340       vector<int> centerElems_;
00341 
00342       /**
00343        * The hash table.
00344        *
00345        * The hash table contains all relevant information of the image to be
00346        * quantized, necessary for the k-Mean algorithms.
00347        *
00348        * It is organized as an array of 4096 (12 bits) hashMapType elements.
00349        *
00350        * This array is then accessed with the lower 12 bits of the color
00351        * value.  The upper 12 bits of the color are used to index the
00352        * proper map, that returns a hashEntry structure, with the correponding
00353        * centroid index for this color and the number of pixels assigned
00354        * to the centroid until now.
00355        *
00356        * In real world images, there will be an average between 5 and 10
00357        * elements per map.
00358        *
00359        * To access theHash directly, you can use the method at(), or put()
00360        */
00361       hashType theHash_;
00362 
00363       /**
00364        * the maximal number of classes
00365        */
00366       const int maxNumberOfClasses_;
00367 
00368       /**
00369        * the number of classes really used in the image
00370        */
00371       int realNumberOfClasses_;
00372 
00373       /**
00374        * maximum number of iterations for the k-Means
00375        */
00376       const int maxNumberOfIterations_;
00377 
00378       /**
00379        * if "Palette-Changing" by iteration < thresholdDeltaPalette
00380        * than stop iterating
00381        * sum(distanceSqr(palNew-palOld))
00382        */
00383       const float thresholdDeltaPalette_;
00384 
00385       /**
00386        * returns a reference to the hash entry for the given pixel
00387        */
00388       inline hashEntry& at(const rgbaPixel& px);
00389 
00390       /**
00391        * put the given pixel in the hash table (increments the counter if
00392        * already exists).
00393        * @return true if the pixel is new added, false otherwise.
00394        */
00395       inline bool put(const rgbaPixel& px);
00396 
00397       /**
00398        * create and initialize the hash table with the image values
00399        */
00400       void initialize(const image& src);
00401 
00402       /**
00403        * get initial palette from hash
00404        */
00405       void getInitialPalette(const cvr::palette& thePalette);
00406 
00407       /**
00408        * iterate to find the clusters
00409        */
00410       void iterate();
00411 
00412       /**
00413        * get a random color from the color hash
00414        */
00415       rgbaPixel getAnImageColor();
00416 
00417       /**
00418        * size of the maps array
00419        */
00420       static const int firstKeySize_;
00421 
00422       /**
00423        * a counter to generate the random colors
00424        */
00425       int lastHashPosition_;
00426 
00427       /**
00428        * Random number generator from 0.0 to 1.0
00429        */
00430       double random() const;
00431     };
00432 
00433   };
00434 
00435 }
00436 
00437 #endif

Generated on Sun Sep 20 22:07:59 2009 for CVR-Lib by Doxygen 1.5.8