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

ltiMeanShiftSegmentation.h

00001 /*
00002  * Copyright (C) 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  * project ....: LTI Digital Image/Signal Processing Library
00025  * file .......: ltiMeanShiftSegmentation.h
00026  * authors ....: Axel Berner
00027  * organization: LTI, RWTH Aachen
00028  * creation ...: 22.6.2001
00029  * revisions ..: $Id: ltiMeanShiftSegmentation.h,v 1.14 2006/02/08 11:27:00 ltilib Exp $
00030  */
00031 
00032 #ifndef _LTI_MEAN_SHIFT_SEGMENTATION_H_
00033 #define _LTI_MEAN_SHIFT_SEGMENTATION_H_
00034 
00035 #include "ltiSegmentation.h"
00036 #include "ltiImage.h"
00037 #include "ltiTimer.h"
00038 
00039 namespace lti {
00040   /**
00041    * This is the implementation of the mean shift segmentation algorithm.
00042    * It is described in
00043    *
00044    * D. Comaniciu, P. Meer,
00045    * "Mean Shift: A Robust Approach toward Feature Space Analysis"
00046    * appeared in IEEE Trans. Pattern Analysis Machine Intell. Vol. 24, No. 5,
00047    * 603-619, 2002
00048    * (original link <a href="http://www.caip.rutgers.edu/~comanici/">
00049    * here </a>)
00050    *
00051    * http://www.caip.rutgers.edu/~comanici/Papers/MsRobustApproach.pdf
00052    *
00053    * The code here is based on the code of the original authors, modified
00054    * extensively for the use with the LTI-Lib.  It has changed a lot since
00055    * then to provide more functionality and configuration options.
00056    *
00057    * There are two implementations available:
00058    *
00059    * The classic implementation is selected setting the parameter
00060    * parameters::classicAlgorithm to \c true.  It is based on an old code
00061    * example published by Comaniciu and colleagues a few years ago.  This
00062    * implementation was not as good as the newer version, but was already
00063    * available in the LTI-Lib.  Since several applications were adapted to use
00064    * that mean-shift version, the default behaviour of this functors has not
00065    * been changed.
00066    *
00067    * The new implementation is an adaption of Comaniciu and Meer's EDISON code
00068    * (http://www.caip.rutgers.edu/riul/research/robust.html).  It can be
00069    * selected setting parameters::classicAlgorithm to \c false.  Decisive for
00070    * the result of the new implementation is the choice of the parameters
00071    * parameters::sigmaR, parameters::sigmaS,
00072    * parameters::maxNeighbourColorDistance, and the parameters::speedup.
00073    *
00074    * \warning This functor will be completely reviewed soon.  Its interface
00075    *          may change a little bit to improve its usability.
00076    *          It has now the problem that the parameters for
00077    *          the classic version and the ones for the new algorithmic
00078    *          implementation are different and they shouldn't.
00079    *
00080    * \todo The interface for classic and new algorithms has to be unified and
00081    *       simplified.  There are also several efficiency aspects to be
00082    *       reviewed.
00083    */
00084   class meanShiftSegmentation : public segmentation {
00085   public:
00086     /**
00087      * the parameters for the class meanShiftSegmentation
00088      */
00089     class parameters : public segmentation::parameters {
00090     public:
00091       /**
00092        * default constructor
00093        */
00094       parameters();
00095 
00096       /**
00097        * copy constructor
00098        * @param other the parameters object to be copied
00099        */
00100       parameters(const parameters& other);
00101 
00102       /**
00103        * destructor
00104        */
00105       ~parameters();
00106 
00107       /**
00108        * returns name of this type
00109        */
00110       const char* getTypeName() const;
00111 
00112       /**
00113        * copy the contents of a parameters object
00114        * @param other the parameters object to be copied
00115        * @return a reference to this parameters object
00116        */
00117       parameters& copy(const parameters& other);
00118 
00119       /**
00120        * copy the contents of a parameters object
00121        * @param other the parameters object to be copied
00122        * @return a reference to this parameters object
00123        */
00124       parameters& operator=(const parameters& other);
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        * 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 #     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        * @name Parameters for the old algorithm
00175        */
00176       //@{
00177       /**
00178        * Constants to specify degree of segmentation
00179        */
00180       enum {
00181         /**
00182          * Constant value to specify the quantization option.
00183          */
00184         Quantization = 0,
00185 
00186         /**
00187          * constant value to specify the oversegmentation option.
00188          */
00189         Oversegmentation = 1,
00190 
00191         /**
00192          * constant value to specify the undersegmentation option.
00193          */
00194         Undersegmentation = 2
00195       };
00196 
00197       /**
00198        * Option: 0 Quantization
00199        *         1 Oversegmentation
00200        *         2 Undersegmentation
00201        *
00202        * You should use the given constants instead of the magic numbers...
00203        *
00204        * Default: Undersegmentation
00205        */
00206       int option;
00207 
00208       /**
00209        * Number of rectangles, in which the segmenter looks for a color
00210        *
00211        * If the first rectangle is (0,0,0,0) then an \e auto-segmentation
00212        * mode is activated and colors are taken from the whole image.
00213        * Otherwise the colors will be taken from the given image region.
00214        *
00215        * The number of rectangles specifies the maximal possible number of
00216        * colors for the segmented/quantized image.
00217        *
00218        * If you give only one rectangle with (0,0,0,0) or an empty vector,
00219        * then 50 elements will be assumed.
00220        *
00221        * Default value: vector with 1 element (0,0,0,0)
00222        */
00223       std::vector<rectangle> rects;
00224 
00225       /**
00226        * Maximal number of trials for choosing a valid representing color.
00227        *
00228        * Default: 10
00229        */
00230       int maxTrial;
00231 
00232       /**
00233        * Number of trials for the representing color to converge
00234        *
00235        * Default: 15 trials
00236        */
00237       int trial2converge;
00238 
00239       /**
00240        * How many pixel in promille of the image must have a colorClass.
00241        *
00242        * Each element of the array corresponds to one of the possible options
00243        * (see <code>option</code> parameter)
00244        *
00245        * Default value: {2.5, 5.0, 10.0} for Quantization, Over- and
00246        *                Undersegmentation respectively.
00247        */
00248       double classThreshold[3];
00249 
00250       /**
00251        * Number of trials to pick up randomly a suitable color in the
00252        * image(rect).
00253        *
00254        * Default: 25
00255        */
00256       int maxTrialRandomColor;
00257 
00258 
00259       /**
00260        * Set the minSize (in Pixel) a region must have.
00261        * default: 15
00262        */
00263       int minRegionSize;
00264 
00265       /**
00266        * Multiplication factor for the colorRadius (variance in image)
00267        *
00268        * Only used in auto-segmentation mode (see rects).
00269        *
00270        * Each element of the array corresponds to one of the possible options
00271        * (see <code>option</code> parameter);
00272        *
00273        * Default value: {8.0, 6.0, 4.0} for Quantization, Over- and
00274        *                Undersegmentation respectively.
00275        */
00276       float rectRadius[3];
00277 
00278       /**
00279        * Multiplication factor for the colorRadius(option)
00280        *
00281        * Use in auto-segmentation mode (see rects).
00282        *
00283        * Increase value if too many colors are found, because of a low
00284        * variance(image)
00285        *
00286        * Each element of the array corresponds to one of the possible options
00287        * (see \c option parameter);
00288        *
00289        * Default value: {2.0, 3.0, 4.0} for Quantization, Over- and
00290        *                Undersegmentation respectively.
00291        */
00292       float autoRadius[3];
00293 
00294       /**
00295        * Set the lower limit of a multiplication factor \e v for the
00296        * colorRadius. max( minVar , \e v )
00297        *
00298        * The factor \e v = sqrt((var.l+var.u+var.v)/100)
00299        * depends on the variance of the image in luv.
00300        *
00301        * For images with an homogeneous background and a small object, this
00302        * value could be increased to get better results (for example with 1.0).
00303        *
00304        * Default value: 0.0 (no influence on factor v)
00305        */
00306       float minVar;
00307       //@}
00308 
00309       /**
00310        * @name Parameters for the new algorithm
00311        */
00312       //@{
00313 
00314       /*
00315        * Using the  multivariate normal kernel yields better results
00316        * but is more computational intensive
00317        *
00318        * Default: false
00319        * not yet implemented!
00320        */
00321       bool multivariateNormalKernel;
00322 
00323       /**
00324        * Three types of speed-up techniques
00325        */
00326       enum eSpeedUpType{
00327         NoSpeedup,     /**< Filters the image applying mean shift to each
00328                         *   point.
00329                         *
00330                         *   Advantage: most accurate
00331                         *
00332                         *   Disadvantage : time expensive
00333                         */
00334         MediumSpeedup, /**< Filters the image using previous mode information
00335                         *   to avoid re-applying mean shift to some data
00336                         *   points (is default)
00337                         *
00338                         *   Advantage: maintains high level of accuracy,
00339                         *              large speed up compared to
00340                         *              non-optimized version
00341                         *
00342                         *   Disadvantage: possibly not as accurate as
00343                         *                 non-optimized version
00344                         */
00345         HighSpeedup    /**< filters the image using previous mode information
00346                         *   and window traversals to avoid re-applying mean
00347                         *   shift to some data points
00348                         *
00349                         *   advantage: huge speed up  maintains accuracy good
00350                         *              enough for segmentation
00351                         *   disadvantage: not as accurate as previous filters
00352                         */
00353       };
00354 
00355       /**
00356        * Higher speedup level causes loss of acuracy
00357        *
00358        * Default: MediumSpeedup
00359        */
00360       eSpeedUpType speedup;
00361 
00362       /**
00363        * The spatial radius of the mean shift sphere.
00364        * (the radius in grid space)
00365        *
00366        * Higher values cause longer computation times, and smoother region
00367        * boundaries.
00368        *
00369        * Default value: 5
00370        */
00371       double sigmaS;
00372 
00373       /**
00374        * The range radius of the mean shift sphere.
00375        * (the radius in color space)
00376        *
00377        * Higher values result in less regions
00378        *
00379        * Default value: 5
00380        */
00381       double sigmaR;
00382 
00383       /**
00384        * Regions having a color difference less than this parameter are joined
00385        * together (by the method fuseRegions()).
00386        *
00387        * It should be smaller than sigmaR.
00388        *
00389        * Default value: 3
00390        */
00391       double maxNeighbourColorDistance;
00392 
00393       /**
00394        * If the magnitude of the mean-shift vector is under this
00395        * threshold, it is considered as converged.
00396        *
00397        * Default value: 0.1
00398        */
00399       double thresholdConverged;
00400 
00401       /**
00402        * Choose algorithm by this parameter.
00403        *
00404        * - \c true: the old algorithm (for compatibility reasons still
00405        *            provided)
00406        * - \c false: the new implementation, like in EDISON.
00407        *
00408        * The classic algorithm uses the following parameters:
00409        * - option
00410        * - rects
00411        * - maxTrial
00412        * - trial2converge
00413        * - classThreshold
00414        * - maxTrialRandomColor
00415        * - minRegionSize
00416        * - rectRadius
00417        * - autoRadius
00418        * - minVar
00419        *
00420        * The new algorithm considers the following parameters;
00421        * - maxTrial
00422        * - speedup
00423        * - sigmaS
00424        * - sigmaR
00425        * - maxNeighbourColorDistance
00426        * - thresholdConverged
00427        *
00428        * Default value: true (classic algorithm is used)
00429        */
00430       bool classicAlgorithm;
00431 
00432     };
00433 
00434     /**
00435      * default constructor
00436      */
00437     meanShiftSegmentation();
00438 
00439     /**
00440      * default constructor
00441      */
00442     meanShiftSegmentation(const parameters& par);
00443 
00444     /**
00445      * copy constructor
00446      * @param other the object to be copied
00447      */
00448     meanShiftSegmentation(const meanShiftSegmentation& other);
00449 
00450     /**
00451      * destructor
00452      */
00453     virtual ~meanShiftSegmentation();
00454 
00455     /**
00456      * returns the name of this type ("meanShiftSegmentation")
00457      */
00458     virtual const char* getTypeName() const;
00459 
00460     /**
00461      * Apply the mean shift segmentation algorithm to the given image.
00462      *
00463      * This image will be internally transformed into the Luv color space, as
00464      * proposed by Comaniciu et.al. in their original paper.
00465      *
00466      * @param src image with the source data.
00467      * @param dest image where the result (segmented image) will be left.
00468      * @return true if apply successful or false otherwise.
00469      */
00470     bool apply(const lti::image& src, lti::image& dest);
00471 
00472     /**
00473      * Apply the mean shift segmentation algorithm to the given image.
00474      *
00475      * This image will be internally transformed into the Luv color space, as
00476      * proposed by Comaniciu et.al. in their original paper.
00477      *
00478      * @param src image with the source data.
00479      * @param dest imatrix where the result (region-labels) will be left.
00480      * @return true if apply successful or false otherwise.
00481      */
00482     bool apply(const lti::image& src,
00483                lti::imatrix& dest);
00484 
00485     /**
00486      * Apply the mean shift segmentation algorithm to the given image.
00487      *
00488      * This image will be internally transformed into the Luv color space, as
00489      * proposed by Comaniciu et.al. in their original paper.
00490      *
00491      * @param src image with the source data.
00492      * @param labels imatrix where the result (region-labels) will be left.
00493      * @param colorMap the color palette used
00494      * @return true if apply successful or false otherwise.
00495      */
00496     bool apply(const lti::image& src,
00497                lti::imatrix& labels,
00498                lti::palette& colorMap);
00499 
00500     /**
00501      * Apply the mean shift segmentation algorithm to a color image, which
00502      * has been already split into three channels.  The algorithm will work
00503      * with these channels without converting them into the Luv color space.
00504      * This allows the use of the mean shift segmentation in other color
00505      * spaces than Luv.
00506      *
00507      * @param chnl1 first channel of the source color image.
00508      * @param chnl2 second channel of the source color image.
00509      * @param chnl3 third channel of the source color image.
00510      * @param dest imatrix where the result (region-labels) will be left.
00511      * @return true if apply successful or false otherwise.
00512      */
00513     bool apply(const lti::channel8& chnl1,
00514                const lti::channel8& chnl2,
00515                const lti::channel8& chnl3,
00516                lti::imatrix& dest);
00517 
00518 
00519     /**
00520      * Apply the mean shift segmentation algorithm to the given image.
00521      *
00522      * This image will be internally transformed into the Luv color space, as
00523      * proposed by Comaniciu et.al. in their original paper.
00524      *
00525      * @param src image with the source data.
00526      * @param destFiltered the meanshift filtered image (not
00527      *        available for classic algorithm)
00528      * @param destSegmented the segmented image
00529      * @param destLabels label associating each pixel to a
00530      *        mode and thus a color to each pixel
00531      * @param destColorMap the colors of the found modes
00532      * @return true if apply successful or false otherwise.
00533      */
00534     bool apply(const lti::image& src,
00535          lti::image& destFiltered,
00536          lti::image& destSegmented,
00537          lti::imatrix& destLabels,
00538          lti::palette& destColorMap);
00539 
00540     /**
00541      * filter the image with meanshift algorithm
00542      *
00543      * @param src the image to be filtered
00544      * @param dest the result will be left here
00545      * @return true if apply successful or false otherwise.
00546      */
00547     bool filter(const lti::image& src, lti::image& dest);
00548 
00549     /**
00550      * filter the image with meanshift algorithm
00551      *
00552      * @param srcdest the image to be filtered
00553      * @return true if apply successful or false otherwise.
00554      */
00555     bool filter(lti::image& srcdest);
00556 
00557     /**
00558      * copy data of "other" functor.
00559      * @param other the functor to be copied
00560      * @return a reference to this functor object
00561      */
00562     meanShiftSegmentation& copy(const meanShiftSegmentation& other);
00563 
00564     /**
00565      * returns a pointer to a clone of this functor.
00566      */
00567     virtual functor* clone() const;
00568 
00569     /**
00570      * returns used parameters
00571      */
00572     const parameters& getParameters() const;
00573 
00574   protected:
00575 
00576     /**
00577      * like rgbPixel for RGB-ColorSpace,
00578      * is luvPixel  for LUV-ColorSpace
00579      */
00580     struct luvPixel {
00581       float l,u,v;
00582     };
00583 
00584   private:
00585 
00586     //-----------------------------------------------------------------------
00587     // members used for classic algorithm - not used in new implementation
00588     //-----------------------------------------------------------------------
00589     /**
00590      * @name Classic implementation
00591      */
00592     //@{
00593 
00594     /**
00595      * internal structure to administrate a region list.
00596      */
00597     struct region {
00598       int my_contor;
00599       int my_class;
00600       int my_label;
00601       int *my_region;
00602       region* next_region_str;
00603     };
00604 
00605     /**
00606      * def. number for nonColor in palette(colorMap)
00607      */
00608     static const int nonColor; // set to 255
00609 
00610     static const int FIRST_SIZE; // = 262144 = 2^18
00611     static const int SEC_SIZE;   // = 64     = 2^6
00612 
00613     /**
00614      * radius for searching of similar colors
00615      * depend from variance of image and parms(autoRadius,rectRadius)
00616      */
00617     std::vector<float> fixRadius;
00618 
00619     /**
00620      * color-search-radius
00621      */
00622     float RADIUS;
00623     float RADIUS2; // RADIUS^2
00624 
00625     /**
00626      *  actual number of image pixels that must have a color class
00627      */
00628     int act_threshold;
00629 
00630     /**
00631      * neighbour for images, which are stored in a vector (not matrix)
00632      * for whole image
00633      */
00634     int neigh[8];
00635 
00636     /**
00637      * neighbour for images, which are stored in a vector (not matrix)
00638      * for subImage
00639      */
00640     int neigh_sub[8];
00641 
00642     /**
00643      * image and subimage(rect) splitted in L,U,V - components
00644      */
00645     matrix<int> chL,chU,chV;
00646     matrix<int> chLcurr,chUcurr,chVcurr; // current subImage (def by rect)
00647 
00648     bool        auto_segm; // true for autosegmentation
00649 
00650     int numImgPxl;    //number of pixel of the original image
00651     int numSubimgPxl; //number of pixel of subimage
00652     int numRemPxl;    //number of remaining pixels
00653     int numOrgColors; //number of colors in the original image
00654     int numRemColors; //number of remaining colors
00655 
00656 
00657     int*_col0,*_col1,*_col2;   // LUV color representation of org image
00658 
00659     /**
00660      * map of assigned labels for segmented image
00661      * value = index in colorPalette luvPalSegm[](LUV) and colorMap[](RGB)
00662      */
00663     ubyte* mapAssignedLabels;
00664 
00665     /*
00666      * map of the pixels colors
00667      * value = index of color palette _col0[],_col1[],_col2[]
00668      * mapPxlToColor[0...numSubimgPxl]
00669      */
00670     int* mapPxlToColor;
00671 
00672     /**
00673      * map of remaining pixels
00674      * value = index of original pixel
00675      * mapRemPxl[0...numRemPxl]
00676      */
00677     int* mapRemPxl;
00678 
00679     /**
00680      * map of remaining colors
00681      * value = index of color palette _col0[], col1[], _col2[]
00682      * mapRemColors[0...numRemColors]
00683      */
00684     int* mapRemColors;
00685 
00686     /**
00687      * how many occurences of each remaining color
00688      * value = number of occurences of this color
00689      * howManyEachRemColor[0...numRemColors]
00690      */
00691     int* howManyEachRemColor;
00692 
00693 
00694     /*
00695      *
00696      */
00697     void setRadius(const double r);
00698 
00699     /*
00700      * For non auto segmentation
00701      * Test if the clusters have the same mean, that is return true
00702      * if found color T[rect] is too near to previously found color
00703      * from T[0...rect]
00704      */
00705     bool testSameCluster(int rect, luvPixel T[]);
00706 
00707     /*
00708      *
00709      */
00710     void luv2rgb( luvPixel& final_T, lti::rgbPixel& TI);
00711 
00712     /*
00713      *
00714      */
00715     void convert_RGB_LUV( const lti::image signal,
00716         const int _col_RGB[], const int _col_misc[] );
00717 
00718     /**
00719      * Method that copies the three channels as Luv channels into
00720      * the internal structures.
00721      */
00722     void convert_RGB_LUV( const lti::channel8& chnl1,
00723                           const lti::channel8& chnl2,
00724                           const lti::channel8& chnl3,
00725         const int _col_RGB[], const int _col_misc[] );
00726     /*
00727      * copy a rectangle from the original image into the subimage
00728      * by filling current channels chLcurr,chUcurr, chVcurr and
00729      * determine neighbourhood vector neigh_r
00730      */
00731     void cutRectangle(const rectangle& rect );
00732 
00733     /*
00734      *
00735      */
00736     void init_matr(int _m_colors[]);
00737 
00738     /*
00739      * compute the mean color of N points given by J[] and return it by T
00740      */
00741     void meanColor(const int N, int J[], luvPixel& T);
00742 
00743     /*
00744      * get the color of a pixel within the subimage which
00745      * is located in a  high density region in color space
00746      * by calling N times subsample() and keep the color
00747      * with the highest density
00748      */
00749     bool my_sampling(luvPixel& T, int N);
00750 
00751     /*
00752      * take randomly one of the remaining pixels and call meanColor()
00753      * to compute the mean color of a neighbourhood of 8 pixels
00754      */
00755     void subsample(luvPixel& Xmean);
00756 
00757     /*
00758      * check all remaining points which were not yet selected. If they
00759      * have enough neighbours(1,2,3) converging to T[rect] they are
00760      * also selected for getting T[rect] assigned
00761      * @param my_class[] true if point should get color assigned
00762      * @param selected[] indices of points that get color T[rect] assigned
00763      * @param numSelectedPxl total number of points changing color (directly
00764      *                  selected ones and as neighbours selected points)
00765      */
00766     void add_neigh(bool my_class[], int selected[], int& numSelectedPxl);
00767 
00768     /*
00769      * Update numRemPxl, mapRemPxl[], numRemColors, mapRemColors[]
00770      * and howManyEachRemColor[]
00771      */
00772     void updateTables(const bool my_class[]);
00773 
00774     /*
00775      *
00776      */
00777     void covariance_w(int _m_colors[], luvPixel& m, luvPixel& v);
00778 
00779     /*
00780      *
00781      */
00782     void find_other_neigh(int k, int *my_ptr_tab, region *current_region,
00783         int conn_selected[], bool taken[]);
00784 
00785     /*
00786      * the actual meanshift algorithm: compute median color of the colors
00787      * within a sphere of RADIUS and center final_T in color space
00788      * @param final_T input: center of sphere output: median color
00789      * @param sel_col[] true if this color is inside the sphere
00790      */
00791     void new_auto_loop(luvPixel& final_T, bool sel_col[] );
00792 
00793     /*
00794      *
00795      */
00796     void nauto_loop(luvPixel& final_T, int selected[],
00797         bool my_class[], int& numSelectedPxl);
00798 
00799     /*
00800      * call new_auto_loop() until color T is converged to local maximum
00801      * and return all points touched by moving sphere
00802      * @param selected[] indices of points that change color to T (all points
00803      *                   that have their color touched by the sphere)
00804      * @param my_class[] true if point should get new color T assigned
00805      * @param numSelectedPxl number of points that should get new color T
00806      *         assigned
00807      */
00808     void calcRepresColorAuto (int selected[], bool my_class[],
00809             luvPixel& T, int& numSelectedPxl);
00810 
00811     /*
00812      *
00813      */
00814     void calcRepresColorNAuto(int selected[], bool my_class[],
00815             luvPixel& T, int& numSelectedPxl);
00816 
00817     /*
00818      *
00819      */
00820     void getBestPalEntry(const luvPixel T[], const int n_rects);
00821 
00822     /*
00823      *
00824      */
00825     void try2getPalEntry(const luvPixel T[], const int n_rects);
00826 
00827     /*
00828      *
00829      */
00830     void newPalette(luvPixel T[], int n_rects);
00831 
00832     /*
00833      *
00834      */
00835     void buildHistogram(const lti::image& signal, int* _col_RGB[],
00836           int* _m_colors[], int* _col_misc[]);
00837 
00838     /**
00839      * build the histogram for a split image.
00840      */
00841     void buildHistogram(const lti::channel8& chnl1,
00842                         const lti::channel8& chnl2,
00843                         const lti::channel8& chnl3,
00844                         int* _col_RGB[],
00845                         int* _m_colors[],
00846                         int* _col_misc[]);
00847 
00848     void updateGenclass( int& n_rects,
00849                          const genericVector<bool>& valid_class, luvPixel T[]);
00850 
00851     /*
00852      *
00853      */
00854     void eliminateSmallClasses( int& n_rects, luvPixel T[]);
00855 
00856     /*
00857      *
00858      */
00859     void eliminateRegions(const luvPixel T[], const int my_lim);
00860 
00861     /*
00862      *
00863      */
00864     void destroyRegionList(region *);
00865 
00866     /*
00867      *
00868      */
00869     region* createRegionList(int *my_max_region);
00870 
00871     /*
00872      *
00873      */
00874     void initializations(const lti::image& src, std::vector<rectangle>& rects);
00875 
00876     /**
00877      * initialization for the case when the user gives directly the
00878      * color space (giving three channels)
00879      */
00880     void initializations(const lti::channel8& chnl1,
00881                          const lti::channel8& chnl2,
00882                          const lti::channel8& chnl3,
00883                          std::vector<rectangle>& rects);
00884 
00885     //@}
00886 
00887     //-----------------------------------------------------------------------
00888     // members used for new imlementation - not used in classic algorithm
00889     //-----------------------------------------------------------------------
00890 
00891     /**
00892      * @name new implementation
00893      */
00894     //@{
00895 
00896     /// width and height of original image
00897     int width, height;
00898 
00899     ///number of pixel of original image
00900     int imageSize;
00901 
00902     ///The range dimension is the number of dimensions of color space
00903     int dimensionRange;
00904 
00905     ///The spatial dimension is the number of dimensions of the image lattice
00906     int dimensionSpace;
00907 
00908      ///The dimension of the feature space =  dimensionRange + dimensionSpace
00909     int dimensionFeatureSpace;
00910 
00911     ///represents the original image in luv space
00912     float* imageLuvOrgF;
00913 
00914     ///represents the meanshift filtered image in luv space
00915     float* imageLuvFilteredF;
00916 
00917     ///represents the meanshift filtered image in luv space (rounded integers)
00918     int* imageLuvFilteredI;
00919 
00920     /// contains for each pixel a weight factor
00921     float* weightMap;
00922 
00923     ///assigns a label to each data point associating it to a mode in modes
00924     ///e.g. a data point having label i has mode modes[i]
00925     int * labels;
00926 
00927     ///containes all found modes as luv values (l1,u1,v1,l2,u2,v2,l3,u3,v3,...)
00928     float *modes;
00929 
00930     ///counts the points associated to each mode
00931     vector<int> modePointCounts;
00932 
00933     ///number of found regions
00934     int regionCount;
00935 
00936     ///for debug and analysis information only: counts how many pixels converged in
00937     ///one step, two steps etc...
00938     vector<int> vecTrialsToConverge;
00939 
00940     /**
00941      * initialize members and allocate memory
00942      */
00943     void initialize();
00944 
00945 
00946     /**
00947      * filters the image applying mean shift to each point
00948      * advantage: most accurate
00949      * disadvantage : time expensive
00950      */
00951     void nonOptimizedFilter();
00952 
00953 
00954     /**
00955      * filters the image using previous mode information
00956      * to avoid re-applying mean shift to some data points
00957      * speedup depends on parameter speed
00958      */
00959     void optimizedFilter();
00960 
00961 
00962     /**
00963      * connect neighbouring pixels having the same color values to a region
00964      * by giving them the same label in labels[]
00965      * input: imageLuvFilteredI
00966      * output: labels, modes, regionCount, modePointCounts
00967      */
00968     void connect();
00969 
00970 
00971     /**
00972      * fuse regions with similar color (modes within sphere)
00973      * input: labels, modes, regionCount, modePointCounts
00974      * output: labels, modes, regionCount, modePointCounts
00975      */
00976     void fuseRegions();
00977 
00978     /**
00979      * prune regions that have less than minRegionSize pixels
00980      * input: labels, modes, regionCount, modePointCounts
00981      * output: labels, modes, regionCount, modePointCounts
00982      */
00983     void pruneRegions();
00984 
00985     /**
00986      * build an array of regionAdjacencyLists (raMatrix) containing all
00987      * neighbour regions for each region (used in fuseRegions())
00988      * input: labels, regionCount
00989      * output: raMatrix
00990      */
00991     void buildRegionAdjacencyMatrix();
00992 
00993 
00994     /**
00995      * convert image from rgb (src) to luv (imageLuvOrgF)
00996      */
00997     void rgbToLuv(const image& src);
00998 
00999     /**
01000      * convert image from luv (src) to rgb (dest)
01001      */
01002     void luvToRgb(float* src, image& dest);
01003 
01004 
01005     /**
01006      * convert one luv pixel(src) to one rgb pixel(dest)
01007      */
01008     void luvToRgb(luvPixel src, rgbPixel& dest);
01009 
01010      /**
01011      * free memory allocated by initialize()
01012      */
01013     void freeMemory();
01014 
01015 
01016     /**
01017      * define region adjacency list class
01018      * which has one entry for each neighbour region of this (one) region
01019      * the first entry represents the region itself and not a neighbour
01020      */
01021     class regionAdjacencyList {
01022 
01023     public:
01024 
01025       /**
01026        * the labels of this region
01027        */
01028       int label;
01029 
01030       /**
01031        * the next neighbour of the considered region
01032        */
01033       regionAdjacencyList* next;
01034 
01035       regionAdjacencyList();
01036 
01037       /** insert a region node into the region adjecency list
01038        * return true indicates that the node was inserted
01039        * return false indicates that the node was not inserted
01040        * because this neighbour region is already in the list
01041        */
01042       bool insert(regionAdjacencyList* entry);  
01043 
01044     private:
01045 
01046       // pointer to current and previous entry
01047       regionAdjacencyList *cur, *prev;
01048     };
01049 
01050     //used in fuseRegions()
01051     regionAdjacencyList* raMatrix, *raPool;
01052 
01053     //@}
01054   };
01055 }
01056 
01057 #endif

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