latest version v1.9 - last update 10 Apr 2010 |
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 .......: ltiFastRelabeling.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 16.5.2003 00030 * revisions ..: $Id: ltiFastRelabeling.h,v 1.8 2006/02/08 11:07:26 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_FAST_RELABELING_H_ 00034 #define _LTI_FAST_RELABELING_H_ 00035 00036 #include "ltiModifier.h" 00037 #include "ltiContour.h" 00038 00039 #include <vector> 00040 00041 namespace lti { 00042 /** 00043 * This functor takes a mask (labeled or not), where it is assumed that 00044 * a region must be connected or not and reassignes labels to them in 00045 * a way that each connected region gets its own label. 00046 * 00047 * Derived classes can compute for each of the found object additional 00048 * information like geometric features, bounding boxes, weighted 00049 * probabilities, etc. 00050 */ 00051 class fastRelabeling : public modifier { 00052 public: 00053 /** 00054 * the parameters for the class fastRelabeling 00055 */ 00056 class parameters : public modifier::parameters { 00057 public: 00058 /** 00059 * default constructor 00060 */ 00061 parameters(); 00062 00063 /** 00064 * copy constructor 00065 * @param other the parameters object to be copied 00066 */ 00067 parameters(const parameters& other); 00068 00069 /** 00070 * destructor 00071 */ 00072 ~parameters(); 00073 00074 /** 00075 * returns name of this type 00076 */ 00077 const char* getTypeName() const; 00078 00079 /** 00080 * copy the contents of a parameters object 00081 * @param other the parameters object to be copied 00082 * @return a reference to this parameters object 00083 */ 00084 parameters& copy(const parameters& other); 00085 00086 /** 00087 * copy the contents of a parameters object 00088 * @param other the parameters object to be copied 00089 * @return a reference to this parameters object 00090 */ 00091 parameters& operator=(const parameters& other); 00092 00093 00094 /** 00095 * returns a pointer to a clone of the parameters 00096 */ 00097 virtual functor::parameters* clone() const; 00098 00099 /** 00100 * write the parameters in the given ioHandler 00101 * @param handler the ioHandler to be used 00102 * @param complete if true (the default) the enclosing begin/end will 00103 * be also written, otherwise only the data block will be written. 00104 * @return true if write was successful 00105 */ 00106 virtual bool write(ioHandler& handler,const bool complete=true) const; 00107 00108 /** 00109 * read the parameters from the given ioHandler 00110 * @param handler the ioHandler to be used 00111 * @param complete if true (the default) the enclosing begin/end will 00112 * be also written, otherwise only the data block will be written. 00113 * @return true if write was successful 00114 */ 00115 virtual bool read(ioHandler& handler,const bool complete=true); 00116 00117 # ifdef _LTI_MSC_6 00118 /** 00119 * this function is required by MSVC only, as a workaround for a 00120 * very awful bug, which exists since MSVC V.4.0, and still by 00121 * V.6.0 with all bugfixes (so called "service packs") remains 00122 * there... This method is also public due to another bug, so please 00123 * NEVER EVER call this method directly: use read() instead 00124 */ 00125 bool readMS(ioHandler& handler,const bool complete=true); 00126 00127 /** 00128 * this function is required by MSVC only, as a workaround for a 00129 * very awful bug, which exists since MSVC V.4.0, and still by 00130 * V.6.0 with all bugfixes (so called "service packs") remains 00131 * there... This method is also public due to another bug, so please 00132 * NEVER EVER call this method directly: use write() instead 00133 */ 00134 bool writeMS(ioHandler& handler,const bool complete=true) const; 00135 # endif 00136 00137 // ------------------------------------------------ 00138 // the parameters 00139 // ------------------------------------------------ 00140 00141 /** 00142 * @name General Options 00143 */ 00144 //@{ 00145 00146 /** 00147 * All values in the original mask above or equal this minimum threshold 00148 * will be considered as candidates to relabeling. 00149 * 00150 * Default value: 1 00151 */ 00152 int minThreshold; 00153 00154 /** 00155 * All values in the original mask below or equal this maximum threshold 00156 * will be considered as candidates to relabeling. 00157 * 00158 * Default value: std::numeric_limits<int>::max() 00159 */ 00160 int maxThreshold; 00161 00162 /** 00163 * If true, each integer value in the original image will be considered 00164 * as a new region label. If false, only two "values" will be taken: 00165 * within the threshold interval or outside it. 00166 * 00167 * Default value: true 00168 */ 00169 bool assumeLabeledMask; 00170 00171 /** 00172 * If true, a 4-neighborhood will be used to detect the adjacent pixels, 00173 * otherwise an 8-neighborhood will be used. 00174 * 00175 * Due to the lesser number of required comparisons, the 4-neighborhood 00176 * allows a faster relabeling. Sometimes however the 8-neighborhood 00177 * is required. 00178 * 00179 * Default value: true (i.e. 4-neighborhood) 00180 */ 00181 bool fourNeighborhood; 00182 //@} 00183 00184 /** 00185 * @name Filter objects 00186 */ 00187 //@{ 00188 /** 00189 * If sortSize is true, the object labels will be assigned according to 00190 * the number of pixels of each object. 00191 * 00192 * \warning There is an exception. The label 0 has a special meaning 00193 * and it will always be assigned to the background (everything outside 00194 * the given interval between minThreshold and maxThreshold) 00195 * independently of its size. This means the regions will be sorted 00196 * decreasingly but begining with the second element. The first one is 00197 * always the background. If you set minThreshold to zero, the first 00198 * element is always empty. 00199 * 00200 * Defalut value: false 00201 */ 00202 bool sortSize; 00203 00204 /** 00205 * If the number of pixels of an object is less than the 00206 * minimumObjectSize, it will be assigned to the background label (0). 00207 * 00208 * Default value: 1 (i.e. consider all objects) 00209 */ 00210 int minimumObjectSize; 00211 //@} 00212 00213 }; 00214 00215 /** 00216 * default constructor 00217 */ 00218 fastRelabeling(); 00219 00220 /** 00221 * Construct a functor using the given parameters 00222 */ 00223 fastRelabeling(const parameters& par); 00224 00225 /** 00226 * copy constructor 00227 * @param other the object to be copied 00228 */ 00229 fastRelabeling(const fastRelabeling& other); 00230 00231 /** 00232 * destructor 00233 */ 00234 virtual ~fastRelabeling(); 00235 00236 /** 00237 * returns the name of this type ("fastRelabeling") 00238 */ 00239 virtual const char* getTypeName() const; 00240 00241 /** 00242 * operates on the given %parameter. 00243 * @param srcdest channel8 with the source data. The result 00244 * will be left here too. 00245 * @return true if apply successful or false otherwise. 00246 */ 00247 bool apply(channel8& srcdest) const; 00248 00249 /** 00250 * operates on the given %parameter. 00251 * @param srcdest imatrix with the source data. The result 00252 * will be left here too. 00253 * @return true if apply successful or false otherwise. 00254 */ 00255 bool apply(imatrix& srcdest) const; 00256 00257 /** 00258 * operates on a copy of the given %parameters. 00259 * @param src channel8 with the source data. 00260 * @param dest channel8 where the result will be left. 00261 * @return true if apply successful or false otherwise. 00262 */ 00263 bool apply(const channel8& src,channel8& dest) const; 00264 00265 /** 00266 * operates on a copy of the given %parameters. 00267 * @param src channel8 with the source data. 00268 * @param dest channel8 where the result will be left. 00269 * @return true if apply successful or false otherwise. 00270 */ 00271 bool apply(const channel8& src,imatrix& dest) const; 00272 00273 /** 00274 * operates on a copy of the given %parameters. 00275 * @param src imatrix with the source data. 00276 * @param dest imatrix where the result will be left. 00277 * @return true if apply successful or false otherwise. 00278 */ 00279 bool apply(const imatrix& src,imatrix& dest) const; 00280 00281 /** 00282 * operates on a copy of the given %parameters. 00283 * @param src channel8 with the source data. 00284 * @param dest channel8 where the result will be left. 00285 * @param numPixels number of pixel per new object label 00286 * @return true if apply successful or false otherwise. 00287 */ 00288 bool apply(const channel8& src,channel8& dest,ivector& numPixels) const; 00289 00290 /** 00291 * operates on a copy of the given %parameters. 00292 * @param src channel8 with the source data. 00293 * @param dest channel8 where the result will be left. 00294 * @param numPixels number of pixel per new object label 00295 * @return true if apply successful or false otherwise. 00296 */ 00297 bool apply(const channel8& src,imatrix& dest,ivector& numPixels) const; 00298 00299 /** 00300 * operates on a copy of the given %parameters. 00301 * @param src imatrix with the source data. 00302 * @param dest imatrix where the result will be left. 00303 * @param numPixels number of pixel per new object label 00304 * @return true if apply successful or false otherwise. 00305 */ 00306 bool apply(const imatrix& src,imatrix& dest,ivector& numPixels) const; 00307 00308 /** 00309 * operates on a copy of the given %parameters. 00310 * @param src channel8 with the source data. 00311 * @param dest channel8 where the result will be left. 00312 * @param numPixels number of pixel per new object label 00313 * @param objects for each label o, objects[o] contains all points 00314 * belonging to that object. 00315 * @return true if apply successful or false otherwise. 00316 */ 00317 bool apply(const channel8& src,channel8& dest, 00318 ivector& numPixels,std::vector<areaPoints>& objects) const; 00319 00320 /** 00321 * operates on a copy of the given %parameters. 00322 * @param src channel8 with the source data. 00323 * @param dest channel8 where the result will be left. 00324 * @param numPixels number of pixel per new object label 00325 * @param objects for each label o, objects[o] contains all points 00326 * belonging to that object. 00327 * @return true if apply successful or false otherwise. 00328 */ 00329 bool apply(const channel8& src,imatrix& dest,ivector& numPixels, 00330 std::vector<areaPoints>& objects) const; 00331 00332 /** 00333 * operates on a copy of the given %parameters. 00334 * @param src imatrix with the source data. 00335 * @param dest imatrix where the result will be left. 00336 * @param numPixels number of pixel per new object label 00337 * @param objects for each label o, objects[o] contains all points 00338 * belonging to that object. 00339 * @return true if apply successful or false otherwise. 00340 */ 00341 bool apply(const imatrix& src,imatrix& dest,ivector& numPixels, 00342 std::vector<areaPoints>& objects) const; 00343 00344 /** 00345 * This apply method does not complete the relabeling process. Instead of 00346 * that it returns an incomplete labeled mask and the label equivalences 00347 * vector, with which other functors can efficiently compute other 00348 * information about the found objects. 00349 * 00350 * @param src original labeled or unlabeled mask. 00351 * @param partMask partial labeled mask. 00352 * @param equivLabels vector with the equivalence labels 00353 * @param numObjects number of objects found in the src mask. 00354 * @return true if successful, false otherwise. 00355 * 00356 * The simplest way to get a consistend finished mask (which is directly 00357 * provided in other apply methods) is to assign to each pixel of partMask 00358 * the corresponding equivalent label, i.e. for each x and y, 00359 * partMask.at(y,x) = equivLabels(partMask.at(y,x)). 00360 */ 00361 bool apply(const channel8& src, 00362 channel8& partMask, 00363 ivector& equivLabels, 00364 int& numObjects) const; 00365 00366 /** 00367 * This apply method does not complete the relabeling process. Instead of 00368 * that it returns an incomplete labeled mask and the label equivalences 00369 * vector, with which other functors can efficiently compute other 00370 * information about the found objects. 00371 * 00372 * @param src original labeled or unlabeled mask. 00373 * @param partMask partial labeled mask. 00374 * @param equivLabels vector with the equivalence labels 00375 * @param numObjects number of objects found in the src mask. 00376 * @return true if successful, false otherwise. 00377 * 00378 * The simplest way to get a consistend finished mask (which is directly 00379 * provided in other apply methods) is to assign to each pixel of partMask 00380 * the corresponding equivalent label, i.e. for each x and y, 00381 * partMask.at(y,x) = equivLabels(partMask.at(y,x)). 00382 */ 00383 bool apply(const channel8& src, 00384 imatrix& partMask, 00385 ivector& equivLabels, 00386 int& numObjects) const; 00387 00388 /** 00389 * This apply method does not complete the relabeling process. Instead of 00390 * that it returns an incomplete labeled mask and the label equivalences 00391 * vector, with which other functors can efficiently compute other 00392 * information about the found objects. 00393 * 00394 * @param src original labeled or unlabeled mask. 00395 * @param partMask partial labeled mask. 00396 * @param equivLabels vector with the equivalence labels 00397 * @param numObjects number of objects found in the src mask. 00398 * @return true if successful, false otherwise. 00399 * 00400 * The simplest way to get a consistend finished mask (which is directly 00401 * provided in other apply methods) is to assign to each pixel of partMask 00402 * the corresponding equivalent label, i.e. for each x and y, 00403 * partMask.at(y,x) = equivLabels(partMask.at(y,x)). 00404 */ 00405 bool apply(const imatrix& src, 00406 imatrix& partMask, 00407 ivector& equivLabels, 00408 int& numObjects) const; 00409 00410 /** 00411 * copy data of "other" functor. 00412 * @param other the functor to be copied 00413 * @return a reference to this functor object 00414 */ 00415 fastRelabeling& copy(const fastRelabeling& other); 00416 00417 /** 00418 * alias for copy member 00419 * @param other the functor to be copied 00420 * @return a reference to this functor object 00421 */ 00422 fastRelabeling& operator=(const fastRelabeling& other); 00423 00424 /** 00425 * returns a pointer to a clone of this functor. 00426 */ 00427 virtual functor* clone() const; 00428 00429 /** 00430 * returns used parameters 00431 */ 00432 const parameters& getParameters() const; 00433 00434 protected: 00435 00436 /** 00437 * Sort labels and eliminate those objects with sizes smaller than the 00438 * given threshold. 00439 * 00440 * @param minSize minimum number of pixels an object must have. 00441 * @param numPixels number of pixels per object. The index of the vector 00442 * corresponds to the label in the given mask. 00443 * After calling this vector is also sorted. 00444 * @param reindex new indices 00445 */ 00446 bool sortLabels(const int minSize, 00447 ivector& numPixels, 00448 ivector& reindex) const; 00449 00450 /** 00451 * Just relabel the destination, but compute also the size of each object. 00452 */ 00453 bool relabelWithArea(const ivector& equivLabels, 00454 const int numObjects, 00455 imatrix& dest, 00456 ivector& numPixels) const; 00457 00458 /** 00459 * Just relabel the destination, but compute also the size of each object. 00460 */ 00461 bool relabelWithArea(const vector<ubyte>& equivLabels, 00462 const int numObjects, 00463 channel8& dest, 00464 ivector& numPixels) const; 00465 00466 }; 00467 } 00468 00469 #endif