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

ltiDistanceTransform.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 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiDistanceTransform.h
00027  * authors ....: Pablo Alvarado, Markus Radermacher
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 22.8.2001
00030  * revisions ..: $Id: ltiDistanceTransform.h,v 1.11 2006/02/07 18:45:23 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_DISTANCE_TRANSFORM_H_
00034 #define _LTI_DISTANCE_TRANSFORM_H_
00035 
00036 #include "ltiImage.h"
00037 #include "ltiMorphology.h"
00038 
00039 namespace lti {
00040 
00041   /**
00042    * This simple morphological operator assumes that the input data is
00043    * a binary image, i.e. there are values 0 and not 0.  It computes the
00044    * minimal distance of a pixel with not-zero value to a zero pixel.
00045    *
00046    * You can choose in the parameters between a 4-Neighborhood or an
00047    * 8-Neighborhood for the computations.  It is also possible to
00048    * compute the euclidean distance transform.
00049    *
00050    * For two pixels p and q with position p(p.x,p.y) and
00051    * q(q.x,q.y) following is valid:
00052    * - the distance in a 4-neighborhood is |p.x-q.x| + |p.y-q.y|
00053    * - the distance in an 8-neighborhood is max(|p.x-q.x|,|p.y-q.y|)
00054    *
00055    * The computation for the 4- and 8-neighborhood based distance
00056    * transform is very efficient and traverses the input channel just
00057    * twice: once from top to bottom and once on the opposite
00058    * direction.  To compute the euclidean distance transform the
00059    * algorithm described in
00060    *
00061    * Calvin R. Maurer Jr., Rensheng Qi, Vijay V. Raghavan: 
00062    * "A Linear Time Algorithm for Computing Exact Euclidean Distance Transforms
00063    *  of Binary Images in Arbitrary Dimensions". 
00064    * IEEE Transactions on Pattern Analysis and Machine Intelligence,
00065    * Vol.25, No. 2, 2003, pp. 265-270
00066    *
00067    * is used.
00068    *
00069    * @ingroup gMorphology
00070    */
00071   class distanceTransform : public morphology {
00072   public:
00073     /**
00074      * the parameters for the class distanceTransform
00075      */
00076     class parameters : public morphology::parameters {
00077     public:
00078       /**
00079        * default constructor
00080        */
00081       parameters();
00082 
00083       /**
00084        * copy constructor
00085        * @param other the parameters object to be copied
00086        */
00087       parameters(const parameters& other);
00088 
00089       /**
00090        * destructor
00091        */
00092       ~parameters();
00093 
00094       /**
00095        * returns name of this type
00096        */
00097       const char* getTypeName() const;
00098 
00099       /**
00100        * copy the contents of a parameters object
00101        * @param other the parameters object to be copied
00102        * @return a reference to this parameters object
00103        */
00104       parameters& copy(const parameters& other);
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& operator=(const parameters& other);
00112 
00113 
00114       /**
00115        * returns a pointer to a clone of the parameters
00116        */
00117       virtual functor::parameters* clone() const;
00118 
00119       /**
00120        * write the parameters in the given ioHandler
00121        * @param handler the ioHandler to be used
00122        * @param complete if true (the default) the enclosing begin/end will
00123        *        be also written, otherwise only the data block will be written.
00124        * @return true if write was successful
00125        */
00126       virtual bool write(ioHandler& handler,const bool complete=true) const;
00127 
00128       /**
00129        * read the parameters from the given ioHandler
00130        * @param handler the ioHandler to be used
00131        * @param complete if true (the default) the enclosing begin/end will
00132        *        be also written, otherwise only the data block will be written.
00133        * @return true if write was successful
00134        */
00135       virtual bool read(ioHandler& handler,const bool complete=true);
00136 
00137 #     ifdef _LTI_MSC_6
00138       /**
00139        * this function is required by MSVC only, as a workaround for a
00140        * very awful bug, which exists since MSVC V.4.0, and still by
00141        * V.6.0 with all bugfixes (so called "service packs") remains
00142        * there...  This method is also public due to another bug, so please
00143        * NEVER EVER call this method directly: use read() instead
00144        */
00145       bool readMS(ioHandler& handler,const bool complete=true);
00146 
00147       /**
00148        * this function is required by MSVC only, as a workaround for a
00149        * very awful bug, which exists since MSVC V.4.0, and still by
00150        * V.6.0 with all bugfixes (so called "service packs") remains
00151        * there...  This method is also public due to another bug, so please
00152        * NEVER EVER call this method directly: use write() instead
00153        */
00154       bool writeMS(ioHandler& handler,const bool complete=true) const;
00155 #     endif
00156 
00157       // ------------------------------------------------
00158       // the parameters
00159       // ------------------------------------------------
00160 
00161       /**
00162        * Four distancetransformation computation types can be choosen:  
00163        * EightNeighbor, FourNeighbor, EuclideanSqr and Euclidean.
00164        *
00165        * For two pixels p and q with position p(p.x,p.y) and
00166        * q(q.x,q.y) following is valid:
00167        * - the distance in a 4-neighborhood is |p.x-q.x| + |p.y-q.y|
00168        * - the distance in an 8-neighborhood is max(|p.x-q.x|,|p.y-q.y|)
00169        * - the distance is euclidean square for (p.x - q.x)^2 + (p.y - q.y)^2 
00170        * - the distance is euclidean for ( (p.x - q.x)^2 + (p.y - q.y)^2 )^1/2
00171        */
00172       enum eDistanceType{
00173         EightNeighborhood, /**< eight neighborhood distance */
00174         FourNeighborhood,  /**< four neighborhood (city block) distance */
00175         EuclideanSqr,      /**< square of euclidean distance */
00176         Euclidean,         /**< euclidean distance */
00177         EightSED,          /**< eight point sequential euclidian
00178                             *   distance mapping 
00179                             */
00180         EightSEDSqr,       /**< square of the eight point sequential
00181                             *   euclidian distance mapping 
00182                             */
00183         FourSED,           /**< four point sequential euclidian
00184                             *   distance mapping 
00185                             */
00186         FourSEDSqr         /**< square of the four point sequential
00187                             *   euclidian distance mapping 
00188                             */
00189       };
00190 
00191       /**
00192        * Kind of distance transform to be computed.  See eDistanceType
00193        * for more information.
00194        *
00195        * Default value: Euclidean
00196        */
00197       eDistanceType distance;
00198     };
00199 
00200     /**
00201      * default constructor
00202      */
00203     distanceTransform();
00204 
00205     /**
00206      * default constructor
00207      */
00208     distanceTransform(const parameters& par);
00209 
00210     /**
00211      * copy constructor
00212      * @param other the object to be copied
00213      */
00214     distanceTransform(const distanceTransform& other);
00215 
00216     /**
00217      * destructor
00218      */
00219     virtual ~distanceTransform();
00220 
00221     /**
00222      * returns the name of this type ("distanceTransform")
00223      */
00224     virtual const char* getTypeName() const;
00225 
00226     /**
00227      * Compute the distance transform of the srcdest channel, i.e. the
00228      * minimal distance from a non-background pixel to a background pixel.
00229      * It will be assumed, that all background pixels have the value 0.0f.
00230      * (any non zero value will be taken as non-background pixel).
00231      *
00232      * The result in the channel will contain for each pixel the
00233      * distance value.  This means, the usual value range from 0.0f to 1.0f 
00234      * is ignored in this functor, providing the distances in "pixel" units.
00235      * 
00236      * @param srcdest channel with the source data.  The result
00237      *                 will be left here too.
00238      * @return true if successful, false otherwise.
00239      */
00240     virtual bool apply(channel& srcdest) const;
00241 
00242     /**
00243      * Compute the distance transform of the srcdest channel, i.e. the
00244      * minimal distance from a non-background pixel to a background pixel.
00245      * It will be assumed, that all background pixels have the value zero.
00246      * (any non zero value will be taken as non-background pixel).
00247      *
00248      * If the size of \a srcdest and form of its non-background
00249      * regions allow distances greater than 255 (the maximal possible
00250      * representable value with a ubyte), the content of the distance
00251      * transform will be invalid.
00252      * 
00253      * @param srcdest channel8 with the source data.  The result
00254      *                 will be left here too.
00255      * @return true if successful, false otherwise.
00256      */
00257     virtual bool apply(channel8& srcdest) const;
00258 
00259     /**
00260      * Compute the distance transform of the \a src channel and leave
00261      * the result in \a dest, i.e. calculate the minimal distance from
00262      * a non-background pixel to a background pixel.  It will be
00263      * assumed, that all background pixels have the value zero.  (any
00264      * non zero value will be taken as non-background pixel).
00265      *
00266      * The result in the channel will contain for each pixel the
00267      * distance value.  This means, the usual value range from 0.0f to 1.0f 
00268      * is ignored in this functor, providing the distances in "pixel" units.
00269      * 
00270      * @param src channel with the source data.
00271      * @param dest channel where the result will be left.
00272      * @return true if successful, false otherwise.
00273      */
00274     virtual bool apply(const channel& src,channel& dest) const;
00275 
00276     /**
00277      * Compute the distance transform of the \a src channel and leave
00278      * the result in \a dest, i.e. calculate the minimal distance from
00279      * a non-background pixel to a background pixel.  It will be
00280      * assumed, that all background pixels have the value zero.  (any
00281      * non zero value will be taken as non-background pixel).
00282      *
00283      * If the size of \a srcdest and form of its non-background
00284      * regions allow distances greater than 255 (the maximal possible
00285      * representable value with a ubyte), the content of the distance
00286      * transform will be invalid.
00287      * 
00288      * @param src channel8 with the source data.
00289      * @param dest channel8 where the result will be left.
00290      * @return true if successful, false otherwise.
00291      */
00292     virtual bool apply(const channel8& src,channel8& dest) const;
00293 
00294     /**
00295      * copy data of "other" functor.
00296      * @param other the functor to be copied
00297      * @return a reference to this functor object
00298      */
00299     distanceTransform& copy(const distanceTransform& other);
00300 
00301     /**
00302      * alias for copy member
00303      * @param other the functor to be copied
00304      * @return a reference to this functor object
00305      */
00306     distanceTransform& operator=(const distanceTransform& other);
00307 
00308     /**
00309      * returns a pointer to a clone of this functor.
00310      */
00311     virtual functor* clone() const;
00312 
00313     /**
00314      * returns used parameters
00315      */
00316     const parameters& getParameters() const;
00317 
00318   protected:
00319     /**
00320      * iteration for distance computation using an 8-Neighborhood
00321      */
00322     void iteration8(channel& chnl) const;
00323 
00324     /**
00325      * iteration for distance computation using an 4-Neighborhood
00326      */
00327     void iteration4(channel& chnl) const;
00328 
00329     /**
00330      * backwards iteration for distance computation using an 8-Neighborhood
00331      */
00332     void iteration8back(channel& chnl) const;
00333 
00334     /**
00335      * backwards iteration for distance computation using an 4-Neighborhood
00336      */
00337     void iteration4back(channel& chnl) const;
00338     
00339     /**
00340      * Method to compute ED for each column of the precomputed
00341      * distance image chnl. The chnl must be the output of a previos
00342      * call to EDT_1D.  Method uses the distance propagation of the
00343      * function voronoiEDT_2D.
00344      */
00345     inline void EDT_2D(channel& chnl) const;
00346         
00347     /**
00348      * queries some distance information for the EDT
00349      */
00350     inline bool removeEDT(const int du,
00351                           const int dv, 
00352                           const int dw,
00353                           const int u,
00354                           const int v,
00355                           const int w) const;
00356         
00357     /**
00358      * fast linear order computation of the accurade euclidean
00359      * distance with voronoi diagrams
00360      */
00361     void voronoiEDT_2D(channel& chnl, const int dim) const;
00362  
00363     /**
00364      * Method computes ED (euclidean distance) for each row pixel of
00365      * the given channel to the closest background pixel. It assumes
00366      * that a background pixel is set to 0.0f and a foreground pixel is
00367      * > 0.0f. All rows without any background pixel will be set to an
00368      * undefined distance (i.e. < 0.0f). The ED is computed with a fast
00369      * and easy forward-backward distance propagation.
00370      */
00371     void EDT_1D(channel& chnl) const;
00372 
00373     /**
00374      * Method computes ED (euclidean distance) for the given channel
00375      * with the 8SED or 4SED (8 or 4 point sequential euclidian
00376      * distance mapping) method.
00377      */
00378     void sedFiltering(channel &chnl, bool useEightSED)const;
00379 
00380     /**
00381      * Calculates the 4SED distance transform.
00382      */
00383     void fourSEDFiltering(channel &chnl, matrix<point> &dist)const;
00384 
00385 
00386     /**
00387      * Calculates the 8SED distance transform.
00388      */
00389     void eightSEDFiltering(channel &chnl, matrix<point> &dist)const;
00390 
00391   private:
00392 
00393     /**
00394      * Nested class for the SED_filtereing Method.
00395      */
00396     class sedMask;
00397   };
00398 
00399   
00400   class distanceTransform::sedMask{
00401   public:
00402     
00403     /**
00404      * inline Constructor
00405      * @param mask a list of points of the mask positions
00406      * @param size the number of points mask contains
00407      */
00408     sedMask(const point mask[], int size);
00409 
00410     /**
00411      *inline Destructor
00412      */
00413     ~sedMask();
00414   
00415     /**
00416      * filters the positoins in dist with the internal mask
00417      * @param pos the position in dist of the filter process
00418      */
00419     void filter(matrix<point> &dist, const point &pos) const;
00420 
00421   private:
00422   
00423     /**
00424      * After called shortest contains the value of the shorter
00425      * (euclidean) of the two given points. If any point contain
00426      * negative values its lenght is not calculated.
00427      */
00428     inline void query_distance(point &shortest, point &other) const;
00429 
00430     /**
00431      * List to points of the filtermask.
00432      *
00433      * Just a reference to extern data
00434      */
00435     const point *const mask_;
00436 
00437     /**
00438      * Number of point stored in mask
00439      */
00440     int size_;
00441   };
00442 
00443 } //namespace lti
00444 
00445 #endif

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