latest version v1.9 - last update 10 Apr 2010 |
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 .......: ltiObjectsFromMask.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 5.10.2000 00030 * revisions ..: $Id: ltiObjectsFromMask.h,v 1.11 2006/02/08 11:33:17 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_OBJECTS_FROM_MASK_H_ 00034 #define _LTI_OBJECTS_FROM_MASK_H_ 00035 00036 #include "ltiTypes.h" 00037 #include "ltiImage.h" 00038 #include "ltiContour.h" 00039 #include "ltiMath.h" 00040 #include "ltiGeometricFeatures.h" 00041 #include "ltiSegmentation.h" 00042 #include "ltiSTLIoInterface.h" 00043 #include <list> 00044 #include "ltiTree.h" 00045 00046 namespace lti { 00047 /** 00048 * This class works on channel8/imatrix to extract connected components 00049 * and describes them as the topological order of "objects" and 00050 * "holes". 00051 * 00052 * In the following example there are four objects, a triangle, 00053 * a rectangle, a circle and a line. There are also two holes. 00054 * The first one is inside the rectangle, the second is inside 00055 * the circle. The circle itself and the line are inside the 00056 * first hole. 00057 * 00058 * \code 00059 * --------------------------------- 00060 * ---*******----------------------- 00061 * ----*****------------------------ 00062 * -----***----***************------ 00063 * ------*-----***************------ 00064 * ------------**-----------**------ 00065 * ------------**---***---*-**------ 00066 * ------------**--**-**--*-**------ 00067 * ------------**---***---*-**------ 00068 * ------------**---------*-**------ 00069 * ------------**-----------**------ 00070 * ------------***************------ 00071 * ------------***************------ 00072 * --------------------------------- 00073 * 00074 * "-" means background 00075 * "*" indicates objects 00076 * \endcode 00077 * 00078 * The topological structure of objects and holes can be 00079 * described as a tree, where odd numbered levels contain 00080 * objects and even numbered contain holes. (Level 0 is 00081 * an exception, because it represents the top-level, which 00082 * in general stands for the whole image. 00083 * 00084 * For the given example the tree looks like this: 00085 * \code 00086 * level 0 image 00087 * /\ 00088 * / \ 00089 * level 1 triangle(*) rectangle(*) 00090 * \ 00091 * \ 00092 * level 2 hole(-) 00093 * /\ 00094 * / \ 00095 * level 3 circle(*) line(*) 00096 * / 00097 * / 00098 * level 4 hole(-) 00099 * \endcode 00100 * 00101 * 00102 * Each node of the tree contains borderPoints, areaPoints and 00103 * ioPoints. The tree can be obtained by using the 00104 * apply(...tree<objectStruct>...) method. 00105 * 00106 * If you are only interested in the objects and don't need the 00107 * holes, then you can use the other apply() methods, which deliver 00108 * a list of borderPoints, ioPoints or areaPoints for each object. 00109 * A labeled mask is also available. 00110 */ 00111 00112 class objectsFromMask : public segmentation { 00113 public: 00114 /** 00115 * the parameters for the class objectsFromMask 00116 */ 00117 class parameters : public segmentation::parameters { 00118 public: 00119 /** 00120 * default constructor 00121 */ 00122 parameters(); 00123 00124 /** 00125 * copy constructor 00126 * @param other the parameters object to be copied 00127 */ 00128 parameters(const parameters& other); 00129 00130 /** 00131 * destructor 00132 */ 00133 ~parameters(); 00134 00135 /** 00136 * returns name of this type 00137 */ 00138 const char* getTypeName() const; 00139 00140 /** 00141 * copy the contents of a parameters object 00142 * @param other the parameters object to be copied 00143 * @return a reference to this parameters object 00144 */ 00145 parameters& copy(const parameters& other); 00146 00147 /** 00148 * returns a pointer to a clone of the parameters 00149 */ 00150 virtual functor::parameters* clone() const; 00151 00152 /** 00153 * write the parameters in the given ioHandler 00154 * @param handler the ioHandler to be used 00155 * @param complete if true (the default) the enclosing begin/end will 00156 * be also written, otherwise only the data block will be written. 00157 * @return true if write was successful 00158 */ 00159 virtual bool write(ioHandler& handler, 00160 const bool complete=true) const; 00161 00162 /** 00163 * write the parameters in the given ioHandler 00164 * @param handler the ioHandler to be used 00165 * @param complete if true (the default) the enclosing begin/end will 00166 * be also written, otherwise only the data block will be written. 00167 * @return true if write was successful 00168 */ 00169 virtual bool read(ioHandler& handler,const bool complete=true); 00170 00171 # ifdef _LTI_MSC_6 00172 /** 00173 * this function is required by MSVC only, as a workaround for a 00174 * very awful bug, which exists since MSVC V.4.0, and still by 00175 * V.6.0 with all bugfixes (so called "service packs") remains 00176 * there... This method is public due to another bug!, so please 00177 * NEVER EVER call this method directly 00178 */ 00179 bool readMS(ioHandler& handler,const bool complete=true); 00180 00181 /** 00182 * this function is required by MSVC only, as a workaround for a 00183 * very awful bug, which exists since MSVC V.4.0, and still by 00184 * V.6.0 with all bugfixes (so called "service packs") remains 00185 * there... This method is public due to another bug!, so please 00186 * NEVER EVER call this method directly 00187 */ 00188 bool writeMS(ioHandler& handler,const bool complete=true) const; 00189 # endif 00190 00191 /** 00192 * A value >= this threshold is regarded as object (*), all 00193 * other values are background (-). 00194 * 00195 * Default is 1 (Only 0 (black) is background). 00196 * 00197 * Possible range is (1..255) */ 00198 int threshold; 00199 00200 /** 00201 * Regards input channel/matrix as a "labeled" mask if true. 00202 * Connected regions with identical label numbers are 00203 * extracted. Note: labels below threshold are regarded 00204 * as background! 00205 * 00206 * Default is false 00207 */ 00208 bool assumeLabeledMask; 00209 00210 /** 00211 * This value defines the minimum size that an object must have 00212 * in order to be detected. Please note that this refers to the size of 00213 * the data structure, <b>not</b> the actual object! I.e. if 00214 * borderPoints are extracted, <tt>minSize</tt> refers to the minimum 00215 * number of border points (which, by the way, is not the border length! 00216 * see eBoundaryDefinition). So, a rough correspondence to the object's 00217 * area is only given if areaPoints are extracted. In other words, the 00218 * meaning of this parameter depends on which of the apply methods is 00219 * used. 00220 * 00221 * Default is 1 00222 */ 00223 int minSize; 00224 00225 /** 00226 * This value defines the maximum recursion depth for object and hole 00227 * extraction. The level number corresponds to the maximum depth of the 00228 * tree. 00229 * 00230 * I.e. level=0: search top-level for objects<br> 00231 * level=1: find holes in top-level objects<br> 00232 * level=2: search objects within holes of 00233 * top-level objects<br> 00234 * level=3: find their holes ... <br> 00235 * 00236 * Default is -1, which means the recursion goes as deep as possible 00237 */ 00238 int level; 00239 00240 /** 00241 * It is possible to close the holes within an object by setting 00242 * this value. This isn't necessary, if for example level==0, since 00243 * holes inside objects aren't considered then anyway. 00244 * 00245 * Default is false 00246 */ 00247 bool meltHoles; 00248 00249 /** 00250 * This %parameter lets the objects be sorted by the size of the 00251 * pointList type used. This option will be ignored for the 00252 * tree-apply(). 00253 * 00254 * Sorting by "size" means sorting considering the size of the 00255 * pointList used in each specific apply() method. I.e. for areaPoints 00256 * this will be the number of area pixels, for border points, 00257 * the number of pixels at the border, and for ioPoints the number of 00258 * input-output points. 00259 * 00260 * Default is false 00261 */ 00262 bool sortObjects; 00263 00264 /** 00265 * Use objects' actual area size for sorting (true), or rather the size 00266 * of the data structure itself (false; default). 00267 */ 00268 bool sortByArea; 00269 00270 /** 00271 * Generally the whole input %channel8 / %imatrix is as top-level 00272 * for detection. Instead you may specify any region for search with 00273 * this parameter. 00274 * Default is an empty list, which means the whole %channel8 / %imatrix 00275 * will be used. 00276 */ 00277 lti::ioPoints ioSearchAreaList; 00278 }; 00279 00280 /** 00281 * This node-structure for storing information about all 00282 * objects and holes in the tree. 00283 */ 00284 class objectStruct : public ioObject { 00285 public: 00286 ioPoints ioPointList; /**< the ioPoints of the object or hole*/ 00287 areaPoints areaPointList; /**< the areaPoints of the object or 00288 hole*/ 00289 borderPoints borderPointList; /**< the borderPoints of the object or 00290 hole*/ 00291 /** 00292 * Write structure to handler 00293 */ 00294 virtual bool write(ioHandler& handler,const bool complete) const; 00295 00296 /** 00297 * Read structure from handler 00298 */ 00299 virtual bool read(ioHandler& handler,const bool complete); 00300 }; 00301 00302 /** 00303 * constructor 00304 */ 00305 objectsFromMask(); 00306 00307 /** 00308 * copy constructor 00309 * @param other the object to be copied 00310 */ 00311 objectsFromMask(const objectsFromMask& other); 00312 00313 /** 00314 * destructor 00315 */ 00316 virtual ~objectsFromMask(); 00317 00318 /** 00319 * returns the name of this type ("objectsFromMask") 00320 */ 00321 virtual const char* getTypeName() const; 00322 00323 /** 00324 * operates on the given %parameter to extract only objects. 00325 * @param src8 channel8 input-channel 00326 * @param lstIOPointLists std::list of ioPoints 00327 */ 00328 bool apply(const channel8& src8, 00329 std::list<ioPoints>& lstIOPointLists); 00330 /** 00331 * operates on the given %parameter to extract only objects. 00332 * @param src matrix<int> input-channel 00333 * @param lstIOPointLists std::list of ioPoints 00334 */ 00335 bool apply(const matrix<int>& src, 00336 std::list<ioPoints>& lstIOPointLists); 00337 00338 /** 00339 * operates on the given %parameter to extract only objects. 00340 * @param src8 channel8 input-channel 00341 * @param lstBorderPointLists std::list of borderPoints 00342 */ 00343 bool apply(const channel8& src8, 00344 std::list<borderPoints>& lstBorderPointLists); 00345 00346 /** 00347 * operates on the given %parameter to extract only objects. 00348 * @param src matrix<int> input-channel 00349 * @param lstBorderPointLists std::list of borderPoints 00350 */ 00351 bool apply(const imatrix& src, 00352 std::list<borderPoints>& lstBorderPointLists); 00353 00354 /** 00355 * operates on the given %parameter to extract only objects. 00356 * @param src8 channel8 input-channel 00357 * @param lstAreaPointLists std::list of areaPoints. The boundary of 00358 * each areaPoints object will be updated. 00359 */ 00360 bool apply(const channel8& src8, 00361 std::list<areaPoints>& lstAreaPointLists); 00362 /** 00363 * operates on the given %parameter to extract only objects. 00364 * @param src matrix<int> input-channel 00365 * @param lstAreaPointLists std::list of areaPoints. The boundary of 00366 * each areaPoints %object will be updated. 00367 */ 00368 bool apply(const matrix<int>& src, 00369 std::list<areaPoints>& lstAreaPointLists); 00370 00371 /** 00372 * operates on the given %parameter to extract only objects. 00373 * @param src8 channel8 input-channel 00374 * @param lstAreaPointLists list of area points. The boundary of 00375 * each areaPoints %object will be updated. 00376 * @param labeledMask returns a matrix of integers, what represent the 00377 * number of the segmented object 00378 */ 00379 bool apply(const channel8& src8, 00380 std::list<areaPoints>& lstAreaPointLists, 00381 matrix<int>& labeledMask); 00382 00383 /** 00384 * operates on the given %parameter to extract only objects. 00385 * @param src matrix<int> input-channel 00386 * @param lstAreaPointLists list of areaPoints. The boundary of 00387 * each areaPoints object will be updated. 00388 * @param labeledMask returns a matrix of integers, what represent the 00389 * number of the segmented object 00390 */ 00391 bool apply(const matrix<int>& src, 00392 std::list<areaPoints>& lstAreaPointLists, 00393 matrix<int>& labeledMask); 00394 00395 /** 00396 * operates on the given %parameter to extract objects AND holes in 00397 * their topological order. 00398 * @param src8 channel8 input-channel 00399 * @param objectTree tree, that contains io-, border- and areaPoints 00400 */ 00401 bool apply(const channel8& src8, 00402 tree<objectStruct>& objectTree); 00403 /** 00404 * operates on the given %parameter to extract objects AND holes in 00405 * their topological order. 00406 * @param src matrix<int> input-channel 00407 * @param objectTree tree, that contains io-, border- and areaPoints 00408 */ 00409 bool apply(const matrix<int>& src, 00410 tree<objectStruct>& objectTree); 00411 00412 /** 00413 * copy data of "other" functor. 00414 * @param other the functor to be copied 00415 * @return a reference to this functor object 00416 */ 00417 objectsFromMask& copy(const objectsFromMask& other); 00418 00419 /** 00420 * returns a pointer to a clone of this functor. 00421 */ 00422 virtual functor* clone() const; 00423 00424 /** 00425 * returns used parameters 00426 */ 00427 const parameters& getParameters() const; 00428 00429 private: 00430 objectStruct m_object; 00431 00432 objectStruct* pObject; 00433 objectStruct* pObject2; 00434 00435 channel8 chain; // temp channel for detected chaincodes 00436 int vres,hres; // resolution of image 00437 int vresm1,hresm1; // resulution of image minus 1 00438 int maxThresh; // = max value of variable-type (eg. channel8: 255) 00439 00440 ioPoints::iterator iterIOPoint; 00441 ioPoints::iterator iterIOPointEnd; 00442 ioPoints::iterator iterIOPointTmp; 00443 00444 static const int markarray[8][8]; 00445 static const int areaarray[8][8]; 00446 static const int xsteparray[8]; 00447 static const int ysteparray[8]; 00448 00449 bool bCalcIoPoints,bCalcBorderPoints,bCalcAreaPoints; 00450 00451 parameters gParams; 00452 00453 tree<objectStruct> objectTree; 00454 00455 std::list<ioPoints>* plstIOPointLists; 00456 std::list<borderPoints>* plstBorderPointLists; 00457 std::list<areaPoints>* plstAreaPointLists; 00458 00459 /** 00460 * This is an internal help function for scanning the matrix reg. Objects 00461 * @param pImg imatrix to be scanned 00462 * @param thresh threshold to be used for infront segmentation 00463 * @param numOfObjects number of objects to be detected 00464 * @param startPoint point for starting the scan 00465 * @param lstBorderPointLists borderPoint list for detected objects 00466 * @param lstIOPointLists ioPoint list for detected objects 00467 * @param calcIOPoints this flag decides calculating the ioPoint list 00468 * @return the number of detected objects 00469 */ 00470 int detectObjects(const imatrix& pImg, 00471 const int& thresh, 00472 lti::ioPoints& lstIOSearchArea, 00473 tree<objectStruct>::node& mNode); 00474 00475 /** 00476 * This is an internal help function for scanning the matrix reg. Objects 00477 * @param pImg imatrix to be scanned 00478 * @param thresh threshold to be used for infront segmentation 00479 * @param numOfObjects number of objects to be detected 00480 * @param startPoint point for starting the scan 00481 * @param lstBorderPointLists borderPoint list for detected objects 00482 * @param lstIOPointLists ioPoint list for detected objects 00483 * @param calcIOPoints this flag decides calculating the ioPoint list 00484 * @return the number of detected objects 00485 */ 00486 int detectObjectsSimple(const imatrix& pImg, 00487 const int& thresh, 00488 lti::ioPoints& lstIOSearchArea, 00489 tree<objectStruct>::node& mNode); 00490 00491 /** 00492 * This is an internal help function for scanning the matrix reg. Objects 00493 * @param pImg imatrix to be scanned 00494 * @param thresh threshold to be used for infront segmentation 00495 * @param numOfObjects number of objects to be detected 00496 * @param startPoint point for starting the scan 00497 * @param lstBorderPointLists borderPoint list for detected objects 00498 * @param lstIOPointLists ioPoint list for detected objects 00499 * @param calcIOPoints this flag decides calculating the ioPoint list 00500 * @return the number of detected objects 00501 */ 00502 int detectObjectsLabeled(const imatrix& pImg, 00503 const int& thresh, 00504 lti::ioPoints& lstIOSearchArea, 00505 tree<objectStruct>::node& mNode); 00506 00507 /** 00508 * This is an internal help function for scanning the matrix reg. Holes 00509 * @param pImg imatrix to be scanned 00510 * @param thresh threshold to be used for infront segmentation 00511 * @param numOfObjects number of objects to be detected 00512 * @param startPoint point for starting the scan 00513 * @param lstBorderPointLists borderPoint list for detected objects 00514 * @param lstIOPointLists ioPoint list for detected objects 00515 * @param calcIOPoints this flag decides calculating the ioPoint list 00516 * @return the number of detected objects 00517 */ 00518 int detectHoles(const imatrix& pImg, 00519 const int& thresh, 00520 lti::ioPoints& lstIOSearchArea, 00521 tree<objectStruct>::node& mNode); 00522 00523 /** 00524 * This is an internal help function for scanning the matrix reg. Holes 00525 * @param pImg imatrix to be scanned 00526 * @param thresh threshold to be used for infront segmentation 00527 * @param numOfObjects number of objects to be detected 00528 * @param startPoint point for starting the scan 00529 * @param lstBorderPointLists borderPoint list for detected objects 00530 * @param lstIOPointLists ioPoint list for detected objects 00531 * @param calcIOPoints this flag decides calculating the ioPoint list 00532 * @return the number of detected objects 00533 */ 00534 int detectHolesSimple(const imatrix& pImg, 00535 const int& thresh, 00536 lti::ioPoints& lstIOSearchArea, 00537 tree<objectStruct>::node& mNode); 00538 00539 /** 00540 * This is an internal help function for scanning the matrix reg. Holes 00541 * @param pImg imatrix to be scanned 00542 * @param thresh threshold to be used for infront segmentation 00543 * @param numOfObjects number of objects to be detected 00544 * @param startPoint point for starting the scan 00545 * @param lstBorderPointLists borderPoint list for detected objects 00546 * @param lstIOPointLists ioPoint list for detected objects 00547 * @param calcIOPoints this flag decides calculating the ioPoint list 00548 * @return the number of detected objects 00549 */ 00550 int detectHolesLabeled(const imatrix& pImg, 00551 const int& thresh, 00552 lti::ioPoints& lstIOSearchArea, 00553 tree<objectStruct>::node& mNode); 00554 00555 /** 00556 * This is an internal help function for building the tree recursively 00557 * @param src imatrix to be scanned 00558 * @param ioPointList ioPointList, within objects are be detected 00559 * @param mNode node under that the detected objects has to be inserted 00560 * @param level the level being detected/analysed 00561 */ 00562 bool buildTree(const imatrix& src, 00563 ioPoints& ioPointList, 00564 tree<objectStruct>::node& mNode, 00565 const int& level); 00566 00567 /** 00568 * This is an internal help function for checking the parameters 00569 */ 00570 bool checkParameters(); 00571 00572 /** A feature extractor required for sorting the objects by size. */ 00573 lti::geometricFeatures featureExtractor; 00574 00575 /** Used for sorting objects by size. */ 00576 static double getArea(void* thisPtr, const areaPoints& ap); 00577 00578 /** Used for sorting objects by size. */ 00579 static double getArea(void* thisPtr, const borderPoints& bp); 00580 00581 /** Used for sorting objects by size. */ 00582 static double getArea(void* thisPtr, const ioPoints& iop); 00583 00584 /** 00585 * Constants for the Canzler codes 00586 */ 00587 enum { 00588 Nothing = 0, /**< constant for nothing */ 00589 Top = 1, /**< constant for left border */ 00590 Right = 2, /**< constant for left border */ 00591 Bottom= 4, /**< constant for left border */ 00592 Left = 8, /**< constant for left border */ 00593 All =15 /**< constant for all borders */ 00594 }; 00595 public: 00596 00597 /** 00598 * Chain code constants (also used in geometricFeatures, hence 00599 * public) 00600 */ 00601 enum { 00602 Invalid = -1, /**< Invalid */ 00603 E = 0, /**< East or Right */ 00604 SE = 1, /**< South-East or Bottom Right */ 00605 S = 2, /**< South or Bottom */ 00606 SW = 3, /**< South-West or Bottom Left */ 00607 W = 4, /**< West or Left */ 00608 NW = 5, /**< North-West or Upper Left */ 00609 N = 6, /**< North or Top */ 00610 NE = 7 /**< North-East or Upper Right */ 00611 }; 00612 }; 00613 } 00614 00615 #endif