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

ltiRegionGrowing.h

00001 /*
00002  * Copyright (C) 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 .......: ltiRegionGrowing.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 28.9.2000
00030  * revisions ..: $Id: ltiRegionGrowing.h,v 1.10 2006/02/08 11:45:11 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_REGION_GROWING_H_
00034 #define _LTI_REGION_GROWING_H_
00035 
00036 #include "ltiObject.h"
00037 #include "ltiTypes.h"
00038 #include "ltiSegmentation.h"
00039 #include "ltiVector.h"
00040 #include "ltiMatrix.h"
00041 #include "ltiImage.h"
00042 #include "ltiMath.h"
00043 
00044 namespace lti {
00045   /**
00046    * This class is used to segmentate an image with a regular
00047    * background.  It uses a set of seed pixels (given in the
00048    * parameters) to start the region growing.  To check the
00049    * similarity, a comparition is done between the pixel value at the
00050    * candidate position and the average value at the
00051    * seed position.  If the difference of these values is lower than a given
00052    * threshold, the pixel will be considered as part of the growing
00053    * region.  It is possible to get automatically values for these thresholds
00054    * if a known background region is given in the parameters.
00055    *
00056    * Example:
00057    *
00058    * \code
00059    * lti::loadBMP loader;
00060    *
00061    * lti::image img;     // the color image to be segmented
00062    * lti::channel8 chnl; // the segmentation mask will be left here
00063    *
00064    * loader.load("img/leo040801_00_019.bmp",img); // read an image
00065    *
00066    * lti::regionGrowing segmenter;         // segmentation functor and
00067    * lti::regionGrowing::parameters param; // its parameters
00068    *
00069    * param.useGaussKernel = true;            // use a gaussian kernel 5x5
00070    * param.localStatisticsKernelSize = 5;
00071    * param.localStatisticsKernelVariance = -1;
00072    *
00073    * param.mode = lti::regionGrowing::parameters::UseGivenThresholds;
00074    * param.averageThresholds = trgbPixel<float>(0.05,0.05,0.05);
00075    * param.edgesThreshold = 0.04;
00076    *
00077    * // do not use all corners as seed-points, just the three following...
00078    * param.seedPoints.resize(3,tpoint<float>(0,0));
00079    * param.seedPoints.at(1).y = 1.0f;
00080    * param.seedPoints.at(2).x = 1.0f;
00081    * param.seedPoints.at(2).y = 1.0f;
00082    *
00083    * // indicate the segmentation functor the user-parameters
00084    * segmenter.setParameters(param);
00085    *
00086    * // segmentate the image and leave the segmentation in the channel
00087    * segmenter.apply(img,chnl);
00088    *
00089    * view1.show(img);  // show original image
00090    * view2.show(chnl); // show the segmentation mask
00091    *
00092    * \endcode
00093    *
00094    * @ingroup gSegmentation
00095    */
00096   class regionGrowing : public segmentation {
00097   public:
00098     /**
00099      * The parameters for the class regionGrowing
00100      */
00101     class parameters : public segmentation::parameters {
00102     public:
00103       /**
00104        * Default constructor
00105        */
00106       parameters();
00107 
00108       /**
00109        * Copy constructor
00110        * @param other the parameters object to be copied
00111        */
00112       parameters(const parameters& other);
00113 
00114       /**
00115        * Destructor
00116        */
00117       ~parameters();
00118 
00119       /**
00120        * Returns name of this type
00121        */
00122       const char* getTypeName() const;
00123 
00124       /**
00125        * Copy the contents of a parameters object
00126        * @param other the parameters object to be copied
00127        * @return a reference to this parameters object
00128        */
00129       parameters& copy(const parameters& other);
00130 
00131       /**
00132        * Returns a pointer to a clone of the parameters
00133        */
00134       virtual functor::parameters* clone() const;
00135 
00136       // -----------------------------------------------------------------
00137 
00138       /**
00139        * Write the parameters in the given ioHandler
00140        * @param handler the ioHandler to be used
00141        * @param complete if true (the default) the enclosing begin/end will
00142        *        be also written, otherwise only the data block will be written.
00143        * @return true if write was successful
00144        */
00145       virtual bool write(ioHandler& handler,
00146                          const bool complete=true) const;
00147 
00148       /**
00149        * Write the parameters in the given ioHandler
00150        * @param handler the ioHandler to be used
00151        * @param complete if true (the default) the enclosing begin/end will
00152        *        be also written, otherwise only the data block will be written.
00153        * @return true if write was successful
00154        */
00155       virtual bool read(ioHandler& handler,const bool complete=true);
00156 
00157 #     ifdef _LTI_MSC_6
00158       /**
00159        * This function is required by MSVC only, as a workaround for a
00160        * very awful bug, which exists since MSVC V.4.0, and still by
00161        * V.6.0 with all bugfixes (so called "service packs") remains
00162        * there...  This method is public due to another bug!, so please
00163        * NEVER EVER call this method directly
00164        */
00165       bool readMS(ioHandler& handler,const bool complete=true);
00166 
00167       /**
00168        * This function is required by MSVC only, as a workaround for a
00169        * very awful bug, which exists since MSVC V.4.0, and still by
00170        * V.6.0 with all bugfixes (so called "service packs") remains
00171        * there...  This method is public due to another bug!, so please
00172        * NEVER EVER call this method directly
00173        */
00174       bool writeMS(ioHandler& handler,const bool complete=true) const;
00175 #     endif
00176 
00177       /**
00178        * Types for the region growing modi
00179        */
00180       enum eMode {
00181         UseGivenThresholds,    /*!< Use the thresholds specified in the
00182                                     parameters */
00183         GetThresholdsRelative, /*!< Use the relative patchPosition to obtain
00184                                     the threshold values */
00185         GetThresholdsAbsolute  /*!< Use the absolute patchPosition to obtain
00186                                     the threshold values */
00187       };
00188 
00189       /**
00190        * Types of "lightness" for the background
00191        */
00192       enum eBackgroundType {
00193         Dark,   /*!< The background has only dark colors */
00194         Medium, /*!< The background has colors with medium intensity */
00195         Light   /*!< The background is white */
00196       };
00197 
00198       /**
00199        * Type (brightness) of the background.  The default value is "Dark".
00200        */
00201       eBackgroundType backgroundType;
00202 
00203       /**
00204        * If this variable is "true", the local region will be specified
00205        * by a gassian filter with the given (local region) size and variance.
00206        * If "false", a rectangular filter will be used.  The default value is
00207        * "false"
00208        */
00209       bool useGaussKernel;
00210 
00211       /**
00212        * Size of the filter kernel used to specify a local region.
00213        * The default value is 5
00214        */
00215       int localStatisticsKernelSize;
00216 
00217       /**
00218        * Variance of the filter kernel used to specify a local region
00219        * (used only if useGaussKernel is true).  The default value is
00220        * "-1", which meaning is described in gaussKernel
00221        */
00222       double localStatisticsKernelVariance;
00223 
00224       /**
00225        * Size of a gaussian kernel used to low-pass-filter the final
00226        * segmentated mask.
00227        */
00228       int smoothingKernelSize;
00229 
00230       /**
00231        * Smoothing threshold.  After the first segmentation, all pixels
00232        * will be assigned to the background or the object.  The smoothing
00233        * filter will generate at the borders of the objects values between
00234        * 0 (background) and 1 (object).  This value will determine which values
00235        * will be considered as object.
00236        *
00237        * The default value is 0.6
00238        */
00239       float smoothingThreshold;
00240 
00241       /**
00242        * Specify the position in the image or channel, where the
00243        * values for the "background" can be taken.
00244        *
00245        * If the mode is GetThresholdsRelative, the values of the
00246        * coordinates must be between 0.0 and 1.0.  The absolute
00247        * coordinates will be calculated multiplying this values with
00248        * the size of the image to be segmented.
00249        *
00250        * If the mode is GetThresholdsAbsolute, this parameters should
00251        * contain the absolute coordinates for the background patch.
00252        */
00253       trectangle<float> patchPosition;
00254 
00255       /**
00256        * Specify how to obtain the threshold values to considered a pixel
00257        * similar to the seed or not.
00258        */
00259       eMode mode;
00260 
00261       /**
00262        * The scale factor allows a faster calculation for the segmentation
00263        * mask, but with a lower boundary detection accuracy.
00264        */
00265       int scaleFactor;
00266 
00267       /**
00268        * Used by the UseGivenThresholds-mode for the segmentation of a
00269        * channel or channel8.  This value MUST be between 0.0 and 1.0
00270        * (The channel8 values will be divided by 255 before the comparitions)
00271        */
00272       float averageThreshold;
00273 
00274       /**
00275        * Used by the UseGivenThresholds-mode for the segmentation of a
00276        * color image.  Each component value must be between 0.0 and 1.0
00277        *
00278        */
00279       trgbPixel<float> averageThresholds;
00280 
00281       /**
00282        * Used by the UseGivenThresholds-mode for the segmentation of a
00283        * channel or channel8.  This value must be between 0.0 and 1.0.
00284        * (The channel8 values will be divided by 255 before the comparitions)
00285        *
00286        */
00287       float edgesThreshold;
00288 
00289       /**
00290        * A list with the relative positions for the starting seed points
00291        * can be specified here.  The valid values for each coordinate are
00292        * between 0.0f and 1.0f.  The default values are the four corners
00293        * (i.e. (0,0),(0,1),(1,0),(1,1) )
00294        */
00295       vector< tpoint<float> > seedPoints;
00296     };
00297 
00298     /**
00299      * Default constructor
00300      */
00301     regionGrowing();
00302 
00303     /**
00304      * Default constructor with parameters
00305      */
00306     regionGrowing(const parameters& par);
00307 
00308     /**
00309      * Copy constructor
00310      * @param other the object to be copied
00311      */
00312     regionGrowing(const regionGrowing& other);
00313 
00314     /**
00315      * Destructor
00316      */
00317     virtual ~regionGrowing();
00318 
00319     /**
00320      * Returns the name of this type ("regionGrowing")
00321      */
00322     virtual const char* getTypeName() const;
00323 
00324     /**
00325      * Operates on the given parameter.
00326      *
00327      * The background-pixels will be set to 0,128 or 255 depending on
00328      * the parameter "backgroundType".
00329      *
00330      * @param srcdest channel8 with the source data.  The result
00331      *                 will be left here too.
00332      * @return a reference to the <code>srcdest</code>.
00333      */
00334     channel8& apply(channel8& srcdest) const;
00335 
00336     /**
00337      * Operates on the given parameter.
00338      *
00339      * The background-pixels will be set to 0, 0.5 or 1.0 depending on
00340      * the parameter "backgroundType".
00341      *
00342      * @param srcdest channel with the source data.  The result
00343      *                 will be left here too.
00344      * @return a reference to the <code>srcdest</code>.
00345      */
00346     channel& apply(channel& srcdest) const;
00347 
00348     /**
00349      * Operates on the given parameter.
00350      *
00351      * The background-pixels will be set to black, grey or white depending on
00352      * the parameter "backgroundType".
00353      *
00354      * @param srcdest image with the source data.  The result
00355      *                 will be left here too.
00356      * @return a reference to the <code>srcdest</code>.
00357      */
00358     image& apply(image& srcdest) const;
00359 
00360     /**
00361      * Operates on a copy of the given %parameters.
00362      *
00363      * @param src channel8 with the source data.
00364      * @param dest channel8 where the segmentation mask will be left.
00365      *             This mask contains 0 for a background point and
00366      *             (usually) 255 for an object point.
00367      * @return a reference to the <code>dest</code>.
00368      */
00369     channel8& apply(const channel8& src,channel8& dest) const;
00370 
00371     /**
00372      * Operates on a copy of the given %parameters.
00373      * @param src channel with the source data.
00374      * @param dest channel8 where the segmentation mask will be left.
00375      *             This mask contains 0 for a background point and
00376      *             (usually) 255 for an object point.
00377      * @return a reference to the <code>dest</code>.
00378      */
00379     channel8& apply(const channel& src,channel8& dest) const;
00380 
00381     /**
00382      * Operates on a copy of the given %parameters.
00383      * @param src image with the source data.
00384      * @param dest channel8 where the segmentation mask will be left.
00385      *             This mask contains 0 for a background point and
00386      *             (usually) 255 for an object point.
00387      * @return a reference to the <code>dest</code>.
00388      */
00389     channel8& apply(const image& src,channel8& dest) const;
00390 
00391     /**
00392      * Copy data of "other" functor.
00393      * @param other the functor to be copied
00394      * @return a reference to this functor object
00395      */
00396     regionGrowing& copy(const regionGrowing& other);
00397 
00398     /**
00399      * Returns a pointer to a clone of this functor.
00400      */
00401     virtual functor* clone() const;
00402 
00403     /**
00404      * Returns used parameters
00405      */
00406     const parameters& getParameters() const;
00407 
00408 
00409   protected:
00410     static float sqroot(const float& x) {
00411       return static_cast<float>(sqrt(x));
00412     };
00413 
00414     static int sqroot(const int& x) {
00415       return static_cast<int>(sqrt(x));
00416     };
00417 
00418     /**
00419      * The pixel at position "neighbour" will be compared with the average
00420      * value corresponding to the position "seed".
00421      *
00422      * The Codition for similarity proof if the absolute value of
00423      * the difference between the channel value at "neighbour" and the
00424      * local average on the "seed"-position is lower than the given
00425      * avrgThreshold
00426      *
00427      */
00428     inline bool similar(const ubyte& neighbour,
00429                         const ubyte& avrgAtSeed,
00430                         const int& avrgThreshold) const {
00431       return (abs(int(neighbour)-int(avrgAtSeed))<=avrgThreshold);
00432     }
00433 
00434     /**
00435      * The pixel at position "neighbour" will be compared with the average
00436      * value corresponding to the position "seed".
00437      *
00438      * The Codition for similarity proof if the absolute value of
00439      * the difference between the channel value at "neighbour" and the
00440      * local average on the "seed"-position is lower than the given
00441      * avrgThreshold
00442      *
00443      */
00444     inline bool similar(const float& neighbour,
00445                         const float& avrgAtSeed,
00446                         const float& avrgThreshold) const {
00447       return (fabs(neighbour - avrgAtSeed)<=avrgThreshold);
00448     }
00449 
00450     /**
00451      * All pixels at img for which the mask is 0 will be set to the given
00452      * value.  The mask and img MUST have the same size!
00453      */
00454     template <class T>
00455     void mask(matrix<T>& img,const channel8& msk,const T& background) const {
00456       channel8::const_iterator cit,ce;
00457       typename matrix<T>::iterator it;
00458       for (cit=msk.begin(),ce=msk.end(),it=img.begin();
00459            cit!=ce;
00460            cit++,it++) {
00461         if ((*cit) == 0) {
00462           (*it)=background;
00463         }
00464       }
00465     }
00466 
00467     /**
00468      * Operates on a copy of the given %parameters.
00469      * @param src image with the source data.
00470      * @param dest the mask will be 0 for background pixels
00471      * @return a reference to the <code>dest</code>.
00472      */
00473     channel8& segmentate(const image& src,channel8& dest) const;
00474 
00475     /**
00476      * Operates on a copy of the given %parameters.
00477      * @param src image with the source data.
00478      * @param dest the mask will be 0 for background pixels
00479      * @return a reference to the <code>dest</code>.
00480      */
00481     channel8& segmentate(const channel& src,channel8& dest) const;
00482   };
00483 }
00484 
00485 #endif

Generated on Sat Apr 10 15:26:04 2010 for LTI-Lib by Doxygen 1.6.1