latest version v1.9 - last update 10 Apr 2010 |
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