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

ltiCoilBackgroundSegmentation.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 Digital Image/Signal Processing Library
00026  * file .......: ltiCoilBackgroundSegmentation.h
00027  * authors ....: Helmuth Euler
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 29.4.2003
00030  * revisions ..: $Id: ltiCoilBackgroundSegmentation.h,v 1.9 2006/02/07 18:37:08 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_COILBACKGROUND_SEGMENTATION_H_
00034 #define _LTI_COILBACKGROUND_SEGMENTATION_H_
00035 
00036 #include "ltiImage.h"
00037 #include "ltiSegmentation.h"
00038 #include "ltiKMColorQuantization.h"
00039 #include "ltiSparseMatrix.h"
00040 
00041 namespace lti {
00042   /**
00043    * The coilBackgroundSegmentation functor tries to detect which pixels 
00044    * belong to the background and which not. It is quite slow, so it should be
00045    * used mainly for static applications where the mask has to be generated
00046    * only once and without any matter of time.
00047    *
00048    * For proper functionality there are some assumtions/requirements:
00049    *
00050    * - The background has to be almost homogeneous. (The functor works best 
00051    *   with black background, but this is not necessary.)
00052    * - There is a high probability that the border of the image
00053    *   contains only background pixels and the object overlaps the middle
00054    *   of the image.
00055    *
00056    *
00057    * The algorithm works as follows:
00058    *
00059    * At first the colors are quantized into regions using the k-means
00060    * algorithm.  Then two masks are generated, one representing the
00061    * object, the other one the background. These masks serve as a
00062    * basis for a probability estimation which region belongs to object
00063    * or background. After that the masks grow considering these
00064    * results, neighbourhoods and covariance matrices.  This iteration
00065    * is repeated "iteration"-times and finally generates a channel
00066    * containing 0 for background and 255 for the object.
00067    *
00068    * At last some after-treatment is done: Pixels constituting weak
00069    * links are deleted and if there is more than one object estimated,
00070    * only the largest one is kept.  In order to improve results, the
00071    * whole algorithm is reiterated up to "maxNumberBestOfN"-times,
00072    * erasing pixels in the final mask which are not estimated as
00073    * object every time. In the best case these shrinking lasts until
00074    * the final mask doesn´t change any more.
00075    * 
00076    * See the lti::coilBackgroundSegmentation::parameters for more information.
00077    */
00078   class coilBackgroundSegmentation : public segmentation {
00079   public:
00080     /**
00081      * the parameters for the class coilBackgroundSegmentation
00082      */
00083     class parameters : public segmentation::parameters {
00084     public:
00085       /**
00086        * default constructor
00087        */
00088       parameters();
00089 
00090       /**
00091        * copy constructor
00092        * @param other the parameters object to be copied
00093        */
00094       parameters(const parameters& other);
00095 
00096       /**
00097        * destructor
00098        */
00099       ~parameters();
00100 
00101       /**
00102        * returns name of this type
00103        */
00104       const char* getTypeName() const;
00105 
00106       /**
00107        * copy the contents of a parameters object
00108        * @param other the parameters object to be copied
00109        * @return a reference to this parameters object
00110        */
00111       parameters& copy(const parameters& other);
00112 
00113       /**
00114        * copy the contents of a parameters object
00115        * @param other the parameters object to be copied
00116        * @return a reference to this parameters object
00117        */
00118       parameters& operator=(const parameters& other);
00119 
00120 
00121       /**
00122        * returns a pointer to a clone of the parameters
00123        */
00124       virtual functor::parameters* clone() const;
00125 
00126       /**
00127        * write the parameters in the given ioHandler
00128        * @param handler the ioHandler to be used
00129        * @param complete if true (the default) the enclosing begin/end will
00130        *        be also written, otherwise only the data block will be written.
00131        * @return true if write was successful
00132        */
00133       virtual bool write(ioHandler& handler,const bool complete=true) const;
00134 
00135       /**
00136        * read the parameters from the given ioHandler
00137        * @param handler the ioHandler to be used
00138        * @param complete if true (the default) the enclosing begin/end will
00139        *        be also written, otherwise only the data block will be written.
00140        * @return true if write was successful
00141        */
00142       virtual bool read(ioHandler& handler,const bool complete=true);
00143 
00144 #     ifdef _LTI_MSC_6
00145       /**
00146        * this function is required by MSVC only, as a workaround for a
00147        * very awful bug, which exists since MSVC V.4.0, and still by
00148        * V.6.0 with all bugfixes (so called "service packs") remains
00149        * there...  This method is also public due to another bug, so please
00150        * NEVER EVER call this method directly: use read() instead
00151        */
00152       bool readMS(ioHandler& handler,const bool complete=true);
00153 
00154       /**
00155        * this function is required by MSVC only, as a workaround for a
00156        * very awful bug, which exists since MSVC V.4.0, and still by
00157        * V.6.0 with all bugfixes (so called "service packs") remains
00158        * there...  This method is also public due to another bug, so please
00159        * NEVER EVER call this method directly: use write() instead
00160        */
00161       bool writeMS(ioHandler& handler,const bool complete=true) const;
00162 #     endif
00163 
00164       // ------------------------------------------------
00165       // the parameters
00166       // ------------------------------------------------
00167 
00168       /**
00169        * The number of iterations the object- and background-masks take to grow
00170        * outside and inside the object.
00171        *
00172        * Default value: 10
00173        */
00174       int iterations;
00175 
00176       /**
00177        * The number of masks created. From them the final mask will be
00178        * generated with the value zero where not all masks were nonzero.
00179        * 4 is enough for a good result, but values >= 100 will generate 
00180        * the best possible solution (high values will cause a long time
00181        * to do the segmentation).
00182        *
00183        * Minimum value: 2
00184        * Default value: 100
00185        */
00186       int maxNumberBestOfN;
00187 
00188       /**
00189        * The factor the first object- and background-mask is stretchend.
00190        * Values > 1 should be used if the image is larger than 128*128
00191        * pixels in order to get a sharper segmentation around the object.
00192        *
00193        * Minimum value: 1
00194        * Default value: 1
00195        */
00196       float maskFactor;
00197 
00198       /**
00199        * The factor the threshold decinding between object and
00200        * background is stretched.  Lower values will cause better
00201        * results with objects containing many dark spots.  Higher
00202        * values prevent 'noise' outside the object.
00203        *
00204        * Default value: 1.30
00205        */
00206       double thresholdFactor;
00207 
00208       /**
00209       * The mean background color to be expected in order to improve
00210       * results by estimating with another covariance matrix.  If the
00211       * backgroundcolor is unknown use meanBackgroundColor = -1 to
00212       * disable.  Otherwise use only values between 0 and 255.  (See
00213       * also: covarMatrixBackground.)
00214       * 
00215       * Default value: 0 (black)
00216       */
00217       int meanBackgroundColor;
00218 
00219       /**
00220       * The size and shape of the additional covariace matrix.
00221       * Only affecting the result if meanBackgroundColor >= 0.
00222       * (See also: meanBackgroundColor)
00223       *
00224       * Default value: 100 on the main diagonal, 0 otherwise
00225       */
00226       dmatrix covarMatrixBackground;
00227     };
00228 
00229     /**
00230      * default constructor
00231      */
00232     coilBackgroundSegmentation();
00233 
00234     /**
00235      * copy constructor
00236      * @param other the object to be copied
00237      */
00238     coilBackgroundSegmentation(const coilBackgroundSegmentation& other);
00239 
00240     /**
00241      * destructor
00242      */
00243     virtual ~coilBackgroundSegmentation();
00244 
00245     /**
00246      * returns the name of this type ("coilBackgroundSegmentation")
00247      */
00248     virtual const char* getTypeName() const;
00249 
00250     /**
00251      * generates a mask with the value 255 where the object is estimated
00252      * and 0 for the background.
00253      *
00254      * @param src image with the source data
00255      * @param result the resulting mask
00256      * @return true if apply successful or false otherwise
00257      */
00258     bool apply(const image& src,channel8& result);
00259 
00260     /**
00261      * copy data of "other" functor.
00262      * @param other the functor to be copied
00263      * @return a reference to this functor object
00264      */
00265     coilBackgroundSegmentation& copy(const coilBackgroundSegmentation& other);
00266 
00267     /**
00268      * alias for copy member
00269      * @param other the functor to be copied
00270      * @return a reference to this functor object
00271      */
00272     coilBackgroundSegmentation& 
00273     operator=(const coilBackgroundSegmentation& other);
00274 
00275     /**
00276      * returns a pointer to a clone of this functor.
00277      */
00278     virtual functor* clone() const;
00279 
00280     /**
00281      * returns used parameters
00282      */
00283     const parameters& getParameters() const;
00284 
00285   protected:
00286 
00287     /**
00288      * type combining the region with its mean color, probability
00289      * and relation to background and object
00290      */
00291     struct TmeanProbability {
00292       float sumProbability;         /// sum of the regionwide probability
00293       int appearanceCounter;        /// number of pixels in this region
00294       float meanProbability;        /// mean probability for the region
00295       int sumColorRed;              /// sum of the regionwide red-value
00296       int sumColorGreen;            /// sum of the regionwide green-value
00297       int sumColorBlue;             /// sum of the regionwide blue-value
00298       rgbPixel meanColor;           /// mean color for the region
00299       bool labelToObjectVector;     /// true if region belongs to object
00300       bool labelToBackgroundVector; /// true if region belongs to background
00301     };
00302 
00303     /**
00304      * delete such positions in the mask
00305      * \code
00306      *    ** **        *****
00307      *    ** **        *****
00308      *    **x**          x
00309      *    ** **        *****
00310      *    ** **        *****
00311      * \endcode
00312      * @param ch8 the channel8 to be optimized
00313      */
00314     void deleteWeakLinks(channel8& ch8) const;
00315 
00316     /**
00317      * calculating the inverted covariance matrix under consideration of 
00318      * the object/background mask
00319      * @param img the image to be considered
00320      * @param mask the mask which pixels from img should be used
00321      * @param mean the meanvalue (center) of the covarianve matrix is returned 
00322      *        here
00323      * @param covarMatrix the resulting matrix is returned here
00324      * @return true if succesfull
00325      */
00326     bool getInvertedCovarMatrixForMask(const image& img, 
00327                                        channel8& mask, 
00328                                        trgbPixel<double>& mean, 
00329                                        dmatrix& covarMatrix) const;
00330 
00331     /**
00332      * checking if a given color is close enough to the covariance matrix
00333      * @param mean the center of the covarianve matrix is considered here
00334      * @param covarMatrix the covariance matrix to be considered
00335      * @param xMinusM pixel with the color to be checked
00336      * @return true if succesfull
00337      */
00338     bool checkColorReasonable(const trgbPixel<double>& mean, 
00339                               const dmatrix& covarMatrix,
00340                               const rgbPixel& xMinusM) const;
00341 
00342     /**
00343      * building the background mask under consideration of
00344      * neighbourhoods, covariance matrix and probabilities
00345      *
00346      * @param img the image to be considered
00347      * @param ch8MaskChannel the mask estimating the background
00348      * @param intSparseMat matix containing which regions are neighbours
00349      * @param meanProbabilityList a list containing mean probability, color and
00350      *        relation towards background and object for each region
00351      * @param newLabelsMatrix matrix containing the labelnumber for each pixel
00352      * @param converged true if no change took place
00353      * @return true if succesfull
00354      */
00355     bool growOutsideObject(const image& img, 
00356                            channel8& ch8MaskChannel, 
00357                            sparseMatrix<int>& intSparseMat,
00358                            std::vector<TmeanProbability>& meanProbabilityList,
00359                            matrix<int>& newLabelsMatrix,
00360                            bool& converged) const;
00361     
00362     /**
00363      * building the object mask under consideration of neighbourhoods,
00364      * covariance matrix and probabilities
00365      *
00366      * @param img the image to be considered
00367      * @param ch8MaskChannel the mask estimating the object
00368      * @param intSparseMat matix containing which labels are related
00369      * @param meanProbabilityList a list containing mean probability, color and
00370      *        relation towards background and object for each region
00371      * @param newLabelsMatrix matrix containing the labelnumber for each pixel
00372      * @param converged true if no change took place
00373      * @return true if succesfull
00374      */
00375     bool growInsideObject(const image& img,
00376                           channel8& ch8MaskChannel,
00377                           sparseMatrix<int>& intSparseMat,
00378                           std::vector<TmeanProbability>& meanProbabilityList,
00379                           matrix<int>& newLabelsMatrix,
00380                           bool& converged) const;
00381   };
00382 }
00383 
00384 #endif

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