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

ltiCWAGMSegmentation.h

00001 /*
00002  * Copyright (C) 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-Lib: Image Processing and Computer Vision Library
00026  * file .......: ltiCWAGMSegmentation.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 30.6.2003
00030  * revisions ..: $Id: ltiCWAGMSegmentation.h,v 1.2 2006/02/07 18:33:41 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_CWAGM_SEGMENTATION_H_
00034 #define _LTI_CWAGM_SEGMENTATION_H_
00035 
00036 #include "ltiMacroSymbols.h"
00037 
00038 // only for compilers different than VC++ 6.0 available
00039 #ifdef _LTI_MSC_6
00040 
00041 #pragma message("Insufficient C++ Template Support for lti::regionGraphMeans.")
00042 #pragma message("You need a newer compiler")
00043 
00044 #else
00045 
00046 
00047 #include "ltiSegmentation.h"
00048 #include "ltiMedianFilter.h"
00049 #include "ltiColorContrastGradient.h"
00050 #include "ltiSplitImage.h"
00051 #include "ltiWatershedSegmentation.h"
00052 #include "ltiRegionGraphMeans.h"
00053 
00054 #include <map>
00055 #include <vector>
00056 
00057 #undef _LTI_DEBUG
00058 //#define _LTI_DEBUG 3
00059 #include "ltiDebug.h"
00060 
00061 namespace lti {
00062 
00063   // ------------------------------------------------------------------------
00064   //
00065   // Color Watershed - Adjacency Graph Merge
00066   //
00067   // ------------------------------------------------------------------------
00068 
00069 
00070   /**
00071    * CWAGM Segmentation
00072    *
00073    * CWAGM means Color Watershed - Adjacency Graph Merge.  It is a
00074    * segmentation algortihms based on low level information introduced in
00075    * P. Alvarado "Segmentation of color images for interactive 3D object
00076    * retrieval".  Ph.D. Thesis. RWTH-Aachen, 2004.
00077    * http://www.bth.rwth-aachen.de/job/disslist.pl
00078    *
00079    * This watershed-based concept is based on the ideas of Haris et.al.
00080    * for a segmentation concept of gray-valued image, extended to color images.
00081    * It uses (optionally) a median filtering to reduce the noise in each color
00082    * channel, computes an over-segmentation with the watershed transformation
00083    * and merge the regions to minimize the mean square error of a piece-wise
00084    * constant image approximation.
00085    */
00086   class cwagmSegmentation : public segmentation {
00087   public:
00088 
00089     /**
00090      * the parameters for the class cwagmSegmentation
00091      */
00092     class parameters : public segmentation::parameters {
00093     public:
00094       /**
00095        * default constructor
00096        */
00097       parameters();
00098 
00099       /**
00100        * copy constructor
00101        * @param other the parameters object to be copied
00102        */
00103       parameters(const parameters& other);
00104 
00105       /**
00106        * destructor
00107        */
00108       ~parameters();
00109 
00110       /**
00111        * returns name of this type
00112        */
00113       const char* getTypeName() const;
00114 
00115       /**
00116        * copy the contents of a parameters object
00117        * @param other the parameters object to be copied
00118        * @return a reference to this parameters object
00119        */
00120       parameters& copy(const parameters& other);
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& operator=(const parameters& other);
00128 
00129       /**
00130        * returns a pointer to a clone of the parameters
00131        */
00132       virtual functor::parameters* clone() const;
00133 
00134       /**
00135        * write the parameters in the given ioHandler
00136        * @param handler the ioHandler to be used
00137        * @param complete if true (the default) the enclosing begin/end will
00138        *        be also written, otherwise only the data block will be written.
00139        * @return true if write was successful
00140        */
00141       virtual bool write(ioHandler& handler,const bool complete=true) const;
00142 
00143       /**
00144        * read the parameters from the given ioHandler
00145        * @param handler the ioHandler to be used
00146        * @param complete if true (the default) the enclosing begin/end will
00147        *        be also written, otherwise only the data block will be written.
00148        * @return true if write was successful
00149        */
00150       virtual bool read(ioHandler& handler,const bool complete=true);
00151 
00152       // ------------------------------------------------
00153       // the parameters
00154       // ------------------------------------------------
00155 
00156       /**
00157        * @name Preprocessing
00158        */
00159       //@{
00160       /**
00161        * A median filter with following parameters is used to denoise the image
00162        *
00163        * If you don't want any pre-smoothing, indicate a kernel size of 1 or
00164        * zero and nothing will be done.
00165        *
00166        * Default value: medianParam::kernelSize = 3;
00167        *                medianParam::boundaryType = Constant;
00168        */
00169       medianFilter::parameters medianParam;
00170 
00171       /**
00172        * Enhance contrast
00173        *
00174        * If set to \a true, the dynamic range of the channels will be
00175        * optimized.
00176        *
00177        * Since the RGB channels will be linearly expanded to map
00178        * min(R,G,B)-max(R,G,B) to the 0-255 range, the colors of the image
00179        * will not be severely altered.
00180        *
00181        * Default value: true
00182        */
00183       bool enhanceContrast;
00184       //@}
00185 
00186       /**
00187        * @name Split-Stage with Watersheds
00188        */
00189       //@{
00190       /**
00191        * The colorSplitter specifies the name of the color space splitting
00192        * functor used to extract the color components of the image, which are
00193        * employed to analyze the edges of the image.
00194        *
00195        * Default value: "lti::splitImageToXYZ"
00196        */
00197       std::string colorSplitter;
00198 
00199       /**
00200        * Parameters for the computations of the color contrast gradient
00201        *
00202        * The result is also the input for the watershed algorithm.
00203        */
00204       colorContrastGradient::parameters colorContrastParam;
00205 
00206       /**
00207        * Watershed transform parameters.
00208        *
00209        * Default: Rainfall method is selected as default and a 8-Neighborhood.
00210        *          The threshold is set to 255 to activate the automatic 
00211        *          threshold detection.
00212        */
00213       watershedSegmentation::parameters watershedParam;
00214 
00215       /**
00216        * To compute which threshold should be used in the watershed
00217        * segmentation, the accumulative histogram of gradient values will be
00218        * used as a probability distribution.  It will be assumed that the 
00219        * probability for a gradient value to be relevant must be greater 
00220        * than the given value.
00221        *
00222        * If you set a value close to zero, almost any gradient value will be
00223        * detected as edge, and an oversegmentation will be produced.
00224        *
00225        * If you set a value close to one, then only very strong gradient
00226        * values will be considered, causing an undersegmentation.
00227        * 
00228        * The automatic threshold computation will be done only if the user set
00229        * the watershedParam.threshold to 255.
00230        *
00231        * The value range must be between 0.0f and 1.0f
00232        * 
00233        * Default value: 0.45f
00234        */
00235       float minProbForWatershedThreshold;
00236       //@}
00237       
00238       /**
00239        * Merging parameters for the graph representation.
00240        *
00241        * Watersheds over-segment images.  The high number of regions detected
00242        * slows down the rest of the algorithms.  Therefore a first "merging"
00243        * stage is done, using an adaption of the distance measure suggested by
00244        * Haris et.al. to also use color images.  All adjacent regions with
00245        * distances under the given threshold will be merged.
00246        *
00247        * A mergeThreshold value close to zero means that only very similar
00248        * regions have to be merged, while a large value indicates to be much
00249        * more tolerant while merging and many regions will be merged.
00250        *
00251        * The threshold indicated within this parameter objects indicate a
00252        * square distance between mean values in the color space weighted by
00253        * the area of the regions, so that this value will be between 0 and
00254        * about 1000000, depending on the regions detected.  You will usually
00255        * give values between 0 and 2000
00256        *
00257        * Default: harisRegionMergeParam::mergeThreshold = 1
00258        *          harisRegionMergeParam::minRegionNumber = 10
00259        */
00260       regionGraphColorHaris::parameters harisRegionMergeParam;
00261     };
00262 
00263     /**
00264      * default constructor
00265      */
00266     cwagmSegmentation();
00267 
00268     /**
00269      * Construct a functor using the given parameters
00270      */
00271     cwagmSegmentation(const parameters& par);
00272 
00273     /**
00274      * copy constructor
00275      * @param other the object to be copied
00276      */
00277     cwagmSegmentation(const cwagmSegmentation& other);
00278 
00279     /**
00280      * destructor
00281      */
00282     virtual ~cwagmSegmentation();
00283 
00284     /**
00285      * returns the name of this type ("cwagmSegmentation")
00286      */
00287     virtual const char* getTypeName() const;
00288 
00289     /**
00290      * operates on a copy of the given %parameters.
00291      * @param src image with the source data.
00292      * @param regions labeled mask as imatrix, where the result will be left.
00293      * @param regionSizes sizes of each region in the \a regions mask.
00294      * @return true if apply successful or false otherwise.
00295      */
00296     bool apply(const image& src,
00297                      imatrix& regions,
00298                      ivector& regionSizes);
00299 
00300     /**
00301      * operates on a copy of the given %parameters.
00302      * @param src image with the source data.
00303      * @param preproc preprocessed image.
00304      * @param regions labeled mask as imatrix, where the result will be left.
00305      * @param regionSizes sizes of each region in the \a regions mask.
00306      * @return true if apply successful or false otherwise.
00307      */
00308     bool apply(const image& src,
00309                      image& preproc,
00310                      imatrix& regions,
00311                      ivector& regionSizes);
00312 
00313 
00314     /**
00315      * Segmentate the image \a src and return many internal partial results
00316      * that can be used in further processing units.
00317      *
00318      * Note that there are several segmentation modes (like color ACA or
00319      * mean-shift segmentation) which do not require the gradient computation.
00320      * These modes will leave the given \a gradMag and \a gradArg untouched.
00321      * This way, the gradients won't be unnecessarily computed and you can
00322      * detect if they are computed or not: just give empty channels and if
00323      * they are still empty after calling this method, you will have to
00324      * compute them, if you need to.
00325      *
00326      * @param src image with the source data.
00327      * @param preproc resulting preprocessed image.
00328      * @param regions labeled mask as imatrix, where the result will be left.
00329      * @param regionSizes sizes of each region in the \a regions mask.
00330      * @param gradMag magnitude of the color gradient
00331      * @param gradArg orientation of the color gradient
00332      * @return true if apply successful or false otherwise.
00333      */
00334     bool apply(const image& src,
00335                      image& preproc,
00336                      imatrix& regions,
00337                      ivector& regionSizes,
00338                      channel& gradMag,
00339                      channel& gradArg);
00340 
00341     /**
00342      * copy data of "other" functor.
00343      * @param other the functor to be copied
00344      * @return a reference to this functor object
00345      */
00346     cwagmSegmentation& copy(const cwagmSegmentation& other);
00347 
00348     /**
00349      * alias for copy member
00350      * @param other the functor to be copied
00351      * @return a reference to this functor object
00352      */
00353     cwagmSegmentation& operator=(const cwagmSegmentation& other);
00354 
00355     /**
00356      * returns a pointer to a clone of this functor.
00357      */
00358     virtual functor* clone() const;
00359 
00360     /**
00361      * returns used parameters
00362      */
00363     const parameters& getParameters() const;
00364 
00365     /**
00366      * Update functor's parameters.
00367      *
00368      * Update the internal state of the functor according to the parameters.
00369      * This special case the functor used to split the image into its color
00370      * componentes is initialized here.
00371      *
00372      * @return true if successful, false otherwise
00373      */
00374     virtual bool updateParameters();
00375     
00376   protected:
00377 
00378     /**
00379      * Preprocess
00380      * Denoise and Enhance Contrast
00381      */
00382     bool preprocess(const image& src,image& dest) const;
00383 
00384     /**
00385      * Split and merge with watersheds.
00386      *
00387      * @param orig original color image
00388      * @param preproc preprocessed image
00389      * @param regions labeld mask with initial partition
00390      * @param regionSizes number of pixels per region
00391      * @param gradM magnitude of the color gradient
00392      * @param gradA orientation of the color gradient
00393      * @param gradHisto histogram of the gradient values
00394      * @param maxGrad maximum gradient value which is also the last value in
00395      *                the histogram.
00396      */
00397     bool worker(const image& orig,
00398                 const image& preproc,
00399                 imatrix& regions,
00400                 ivector& regionSizes,
00401                 channel& gradM,
00402                 channel& gradA,
00403                 vector<float>& gradHisto,
00404                 float& maxGrad);
00405 
00406     /**
00407      * The simplest contrast enhancement consists in mapping the input value
00408      * range of each channel into 0 to 255, each channel independently of
00409      * the others.
00410      *
00411      * src MUST be connected.  (see matrix<T>::mode())
00412      */
00413     bool enhanceContrast(image& src) const;
00414    
00415     /**
00416      * @name local functors
00417      */
00418     //@{
00419     /**
00420      * median filter
00421      */
00422     medianFilter median;
00423 
00424     /**
00425      * Watershed segmentation functor
00426      */
00427     watershedSegmentation watershed;
00428 
00429     /**
00430      * pointer to splitter object
00431      */
00432     splitImage* splitter;
00433 
00434     /**
00435      * color contrast gradient functor used in edge detection
00436      */
00437     colorContrastGradient colorContrast;
00438 
00439     /**
00440      * Haris region merging method (well, my adaption of it)
00441      */
00442     regionGraphColorHaris haris;
00443     //@}
00444 
00445   };
00446 }
00447 
00448 #endif
00449 
00450 #include "ltiUndebug.h"
00451 #endif

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