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

ltiObjectsFromMask.h

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

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