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

ltiContour.h

00001 /*
00002  * Copyright (C) 1998, 1999, 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 Bild/Signal Verarbeitungsbibliothek
00026  * file .......: ltiContour.h
00027  * authors ....: Axon Development Team
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 19.08.98
00030  * revisions ..: $Id: ltiContour.h,v 1.7 2006/02/07 18:40:20 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTICONTOUR_H
00034 #define _LTICONTOUR_H
00035 
00036 #include <list>
00037 #include "ltiTypes.h"
00038 #include "ltiPointList.h"
00039 #include "ltiImage.h"
00040 
00041 namespace lti {
00042 
00043   /**
00044    * Elements of a Chaincode.
00045    * The used directions follows the next diagram:
00046    *
00047    * \code
00048    * NW   N   NE
00049    *    \ | /
00050    * W -  x - E
00051    *    / | \
00052    * SW   S   SE
00053    * \endcode
00054    *
00055    * The "int" value resulting from casting these chain codes is
00056    * proportional to the angle with a proportionality constant of 45°,
00057    * i.e. if 'c' is a chainCode object, then the equivalent direction
00058    * in degrees is 45*int(c.getDirection()).
00059    *
00060    * @ingroup gShape
00061    */
00062   class chainCode {
00063   public:
00064     /**
00065      * Directions used in chain codes
00066      * The used directions follows the next diagram:
00067      *
00068      * \code
00069      * NW   N   NE
00070      *    \ | /
00071      * W -  x - E
00072      *    / | \
00073      * SW   S   SE
00074      * \endcode
00075      *
00076      * The "int" value resulting from casting these chain codes is
00077      * proportional to the angle with a proportionality constant of 45°,
00078      * i.e. if 'c' is a chainCode object, then the equivalent direction
00079      * in degrees is 45*int(c.getDirection()).
00080      */
00081     enum direction {UNKNOWN=-2, /**< Unknown */
00082                     NOMOVE=-1,  /**< No Move */
00083                     E=0,        /**< East (or Right) */
00084                     NE,         /**< North-East (or Right-Up) */
00085                     N,          /**< North (or Up) */
00086                     NW,         /**< North-West (or North-West) */
00087                     W,          /**< West (or West) */
00088                     SW,         /**< South-West (or Left-Down) */
00089                     S,          /**< South (or Down) */
00090                     SE          /**< South-East (or Right-Down) */
00091     };
00092 
00093     /**
00094      * @name Canzler Codes
00095      *
00096      * Given two chain codes for a sequence of three adjacent pixels,
00097      * the Canzler-Codes give you information which borders of the middle
00098      * pixel belong to the boundary.  With the getCanzlerCode you can obtain
00099      * the corresponding coding for the pixel pointed by this chain code, if
00100      * the next chain code is the one given.  They are somehow similar to the
00101      * so called "chain crack codes", but instead of specifying a direction
00102      * of the boundary, they code which "crack codes" belong to the middle
00103      * pixel between two chain codes.
00104      *
00105      * There are 16 Canzler-Codes, that can be obtained by the combination
00106      * of the four values Top, Right, Bottom and Left, which specify that
00107      * the border runs on the top, right, bottom and/or left edge of the
00108      * pixel respectively.
00109      */
00110     //@{
00111     static const ubyte Nothing; /// Nothing has the value 0
00112     static const ubyte Top;     /// Top has value 1 (the first bit)
00113     static const ubyte Right;   /// Right has value 2 (the second bit)
00114     static const ubyte Bottom;  /// Bottom has value 4 (the third bit)
00115     static const ubyte Left;    /// Left has value 8 (the fourth bit)
00116     //@}
00117 
00118     /**
00119      * default constructor
00120      */
00121     chainCode(const direction& v = NOMOVE)
00122       : value(v) {
00123     };
00124 
00125     /**
00126      * constructor to cast an integer
00127      */
00128     chainCode(const int& v) : value(direction(v%8)) {};
00129 
00130     /**
00131      * copy constructor
00132      */
00133     chainCode(const chainCode& other)
00134       : value(other.value) {
00135     };
00136 
00137     /** Constrcutor. This constructor creates a chainCode object using the
00138   sign of the parameters to calculate the direction.
00139   Image-coordinates are used, i.e. a positive "y" implies a
00140   change towards "south", and a positive x implies a
00141   change towards "east". */
00142     chainCode(const int& x,const int& y) : value(NOMOVE) {
00143       fromDeltas(x,y);
00144     };
00145 
00146     /**
00147      * Constructor.This constructor creates a chainCode object using
00148      * two points
00149      */
00150     chainCode(const point& here,const point& next) : value(NOMOVE) {
00151       point tmp(next);
00152       tmp.subtract(here);
00153       fromDeltas(tmp.x,tmp.y);
00154     };
00155 
00156     /**
00157      * returns direction of this chain element
00158      */
00159     inline direction getDirection() const;
00160 
00161     /**
00162      * Possible Direction.returns true if this object contains one of
00163      * the eight posible directions, and false otherwise
00164      */
00165     inline bool isDirection() const;
00166 
00167     /**
00168      * returns next point with start point "here" and using this chainCode.
00169      */
00170     inline point getNext(const point& here) const;
00171 
00172     /**
00173      * returns previous point with start point "here" and using this chainCode.
00174      */
00175     inline point getPrevious(const ipoint& here) const;
00176 
00177     /**
00178      * returns change in x.
00179      * For example, if the value is NW, deltaX() returns -1.
00180      */
00181     inline int deltaX() const;
00182 
00183     /**
00184      * returns change in y.
00185      * For example, if the value is NW, deltaY() returns -1.
00186      */
00187     inline int deltaY() const;
00188 
00189     /**
00190      * returns point with changes in both direction, x and y.
00191      */
00192     inline point delta() const;
00193 
00194     /**
00195      * become other object
00196      */
00197     inline chainCode& operator=(const direction& other) {
00198       return copy(other);
00199     };
00200 
00201     /**
00202      * become other object
00203      */
00204     inline chainCode& copy(const direction& other);
00205 
00206     /**
00207      * become other object
00208      */
00209     inline chainCode& copy(const chainCode& other);
00210 
00211     /**
00212      * become other object
00213      */
00214     inline chainCode& operator=(const chainCode& other) {
00215       return(copy(other));
00216     };
00217 
00218     /**
00219      * compare with another object
00220      */
00221     inline bool compare(const chainCode& other);
00222 
00223     /**
00224      * compare with another object
00225      */
00226     inline bool operator==(const chainCode& other) {
00227       return compare(other);
00228     };
00229 
00230     /**
00231      * compare with another object
00232      */
00233     inline bool compare(const direction& other);
00234 
00235     /**
00236      * compare with another object
00237      */
00238     inline bool operator==(const direction& other) {
00239       return compare(other);
00240     };
00241 
00242     /**
00243      * subtract the angles of the first and second chain code elements and
00244      * leave the result here!
00245      */
00246     inline chainCode& subtract(const chainCode& first,
00247                                const chainCode& second);
00248     /**
00249      * subtract the angle equivalent of the <em>other</em> chainCode
00250      * from *this
00251      */
00252     inline chainCode operator-(const chainCode& other) const {
00253       chainCode tmp;
00254       tmp.subtract(*this,other);
00255       return tmp;
00256     };
00257 
00258     /**
00259      * subtract the angle equivalent of the other chain code from this one.
00260      * The result will be left in this instance, and a reference to it will
00261      * be returned.
00262      */
00263     inline chainCode& subtract(const chainCode& other);
00264 
00265     /**
00266      * subtract another chain code
00267      */
00268     inline chainCode& operator-=(const chainCode& other) {
00269       return subtract(other);
00270     };
00271 
00272     /**
00273      * add the angles of the first and second chain codes
00274      */
00275     inline chainCode& add(const chainCode& first,
00276                           const chainCode& second);
00277 
00278     /**
00279      * add the angles of this and the other chain code
00280      */
00281     inline chainCode operator+(const chainCode& other) const {
00282       chainCode tmp;
00283       tmp.add(*this,other);
00284       return tmp;
00285     };
00286 
00287     /**
00288      * add the angles of the other chain code to this chainCode and
00289      * leave the result in this instance.  Returns a reference to the instance
00290      */
00291     inline chainCode& add(const chainCode& other);
00292 
00293     /**
00294      * add another chain code
00295      */
00296     inline chainCode& operator+=(const chainCode& other) {
00297       return add(other);
00298     };
00299 
00300     /**
00301      * divide chain code equivalent angle with an integer.  The result
00302      * will be left in this instance and a reference to it will be returned
00303      */
00304     inline chainCode& divide(const int& other) {
00305       value=(direction)((int)value/other);
00306       return (*this);
00307     };
00308 
00309     /**
00310      * divide chain code angle with integer.
00311      */
00312     inline chainCode operator/(const int& other) {
00313       chainCode tmp(*this);
00314       tmp.divide(other);
00315       return (tmp);
00316     }
00317 
00318     /**
00319      * return the Canzler Code for the pixel pointed by this chainCode
00320      * if the second chainCode is the one given as parameter.
00321      *
00322      * The result a the bitwise OR of some of the codes Top, Bottom, Left and
00323      * Right.
00324      *
00325      * @param nextChainCode the next chain code of this one in the chain
00326      *                      code sequence.
00327      * @return the canzler bit-coding for the edges of the pixel pointed
00328      *         by this chainCode which are part of the boundary.  The values
00329      *         returned are bit or of the constants Left, Top, Right and
00330      *         Bottom.
00331      */
00332     inline ubyte getCanzlerCode(const chainCode& nextChainCode) const;
00333 
00334   protected:
00335     /**
00336      * Attribute containing the chain code
00337      */
00338     direction value;
00339 
00340     /**
00341      * compute chain code from x and y deltas
00342      */
00343     inline void fromDeltas(const int& x,const int& y);
00344   };
00345 
00346   /**
00347    * read the matrix from the given ioHandler.  The complete flag indicates
00348    * if the enclosing begin and end should be also be readed
00349    *
00350    * @ingroup gStorable
00351    */
00352   bool read(ioHandler& handler,chainCode& cc,const bool complete=true);
00353 
00354   /**
00355    * write the matrix in the given ioHandler.  The complete flag indicates
00356    * if the enclosing begin and end should be also be written or not
00357    *
00358    * @ingroup gStorable
00359    */
00360   bool write(ioHandler& handler,const chainCode& cc,const bool complete=true);
00361 
00362   //declared in ltiPolygonPoints.h
00363   class polygonPoints;
00364   class borderPoints;
00365   class areaPoints;
00366 
00367   /**
00368    * Contour classes: IO-Points.
00369    *
00370    * For the explanation of the contour description in this class, see
00371    * following image:
00372    *
00373    * \code
00374    *   -- 00000000001111111111222222222233
00375    *   -- 01234567890123456789012345678901
00376    *   00 --------------------------------
00377    *   01 --------------------------------
00378    *   02 --------------------------------
00379    *   03 --------BBBB------BBBB----------
00380    *   04 -------B****BBB----B**B---------
00381    *   05 -------B*******B---B***B--------
00382    *   06 ------B*******B-----B*B---------
00383    *   07 -------B*******BBBBB**B---------
00384    *   08 ---------B*************B--------
00385    *   09 --------B**----*********B-------
00386    *   10 --------B**-----********B-------
00387    *   11 -------B**-----*******BB--------
00388    *   12 ------B**-----*******B----------
00389    *   13 ------B**-------******BB--------
00390    *   14 -----B**---------*******B-------
00391    *   15 -----B**--------*********B------
00392    *   16 ----B**-------**********BB------
00393    *   17 ---B***----*******----BB--------
00394    *   18 ----BBBBBBBBB***  --*B----------
00395    *   19 -------------BBBBBBBB-----------
00396    *   20 --------------------------------
00397    *   21 --------------------------------
00398    *   22 --------------------------------
00399    *   23 --------------------------------
00400    *
00401    *  "-" means background and the rest is part of the object.
00402    *  "B" indicates a borderpoint.
00403    *  \endcode
00404    *
00405    *  There are mainly three representations of a contour:
00406    *  - IO-Points. It contains all input and output points for
00407    *    each line.  For example, for the previous image:
00408    *    (8,3)(11,3)(18,3)(21,3)(7,4)(14,4)(19,4)(22,4)...
00409    *    Note that every IO-point is a border point, but not all border
00410    *    points are IO-points.
00411    *  - Border Boints.  It contains a list of the points at the border.
00412    *    Beginning with the point at (8,3) the chain code for our example
00413    *    image is:
00414    *    (8,3)(9,3)(10,3)(11,3)(12,4)(13,4)(14,4)(15,5)(14,6)...
00415    *  - Area-Points.  It contains all points in the object.
00416    *
00417    *  @see lti::borderPoints, lti::areaPoints
00418    *
00419    *  @ingroup gAggregate
00420    *  @ingroup gShape
00421    */
00422   class ioPoints : public pointList {
00423   public:
00424     /**
00425      * default constructor creates an empty io-points list
00426      */
00427     ioPoints();
00428 
00429     /**
00430      * create this pointList as a copy of another pointList
00431      * @param other the pointList to be copied.
00432      */
00433     ioPoints(const ioPoints& other);
00434 
00435     /**
00436      * destructor
00437      */
00438     virtual ~ioPoints();
00439 
00440     /**
00441      * returns the name of this class: "ioPoints"
00442      */
00443     const char* getTypeName() const {return "ioPoints";};
00444 
00445     /**
00446      * creates this io-list from the given area-points-list
00447      *
00448      */
00449     ioPoints& castFrom(const areaPoints& theAreaPoints);
00450 
00451     /**
00452      * creates this io-list from the given border-points-list
00453      */
00454     ioPoints& castFrom(const borderPoints& theBorderPoints);
00455 
00456     /**
00457      * assigment operator (alias for copy(other)).
00458      * @param other the pointList to be copied
00459      * @return a reference to the actual pointList
00460      */
00461     ioPoints& operator=(const ioPoints& other) {
00462       copy(other);
00463       return *this;
00464     };
00465 
00466     /**
00467      * generate ioPoint-list from the given mask image.
00468      *
00469      * This function assumes that the mask contains JUST ONE connected
00470      * object.  To get the biggest object on the mask see the
00471      * lti::objectsFromMask functor.
00472      */
00473     bool getFromMask(const channel8& mask);
00474 
00475     /**
00476      * generate mask from io-points.
00477      *
00478      * The dimensions of the resulting mask are the smallest rectangle to
00479      * contain the point (0,0) (optional) and all points in this list, plus
00480      * 1 pixel in both width and heigth.
00481      * If the boundary of the point list is not up to date, it can
00482      * be calculated if specified in the %parameters:
00483      * @param mask The calculated mask will be stored here
00484      * @param computeBoundary If false, the internal boundary of the
00485      *    point list will be used, otherwise the boundary
00486      *    will be calculated (but NOT updated!!!).
00487      * @param exactBoundaryDimensions If true, the dimensions of the resulting
00488      *    mask will be the smallest rectangle to contain only the points in
00489      *    this list. The origin (0,0) may not be included, therefore a 1:1
00490      *    correspondence of coordinates will generally not be given.
00491      * @param keepMaskData if false, the mask will be initialized with 
00492      *                     zero before getting the area mask.  If true,
00493      *                     the previous mask data is not deleted, but
00494      *                     the mask will be resized if necessary.
00495      * @return true if successful, false otherwise.
00496      */
00497     bool generateMask(channel8& mask,
00498                       const bool computeBoundary=true,
00499                       const bool exactBoundaryDimensions=false,
00500                       const bool keepMaskData=false) const;
00501 
00502     /**
00503      * sort the points of this in ascending order first of y, and than of
00504      * x.
00505      */
00506     void sort();
00507   };
00508 
00509   /**
00510    * Contour classes: Border-Points.
00511    *
00512    * For the explanation of the contour description in this class, see
00513    * following image:
00514    *
00515    * \code
00516    *   -- 00000000001111111111222222222233
00517    *   -- 01234567890123456789012345678901
00518    *   00 --------------------------------
00519    *   01 --------------------------------
00520    *   02 --------------------------------
00521    *   03 --------BBBB------BBBB----------
00522    *   04 -------B****BBB----B**B---------
00523    *   05 -------B*******B---B***B--------
00524    *   06 ------B*******B-----B*B---------
00525    *   07 -------B*******BBBBB**B---------
00526    *   08 ---------B*************B--------
00527    *   09 --------B**----*********B-------
00528    *   10 --------B**-----********B-------
00529    *   11 -------B**-----*******BB--------
00530    *   12 ------B**-----*******B----------
00531    *   13 ------B**-------******BB--------
00532    *   14 -----B**---------*******B-------
00533    *   15 -----B**--------*********B------
00534    *   16 ----B**-------**********BB------
00535    *   17 ---B***----*******----BB--------
00536    *   18 ----BBBBBBBBB***  --*B----------
00537    *   19 -------------BBBBBBBB-----------
00538    *   20 --------------------------------
00539    *   21 --------------------------------
00540    *   22 --------------------------------
00541    *   23 --------------------------------
00542    *
00543    *  "-" means background and the rest is part of the object.
00544    *  "B" indicates a borderpoint.
00545    *  \endcode
00546    *
00547    *  This contour class allows three representations of a contour:
00548    *  - IO-Points. It contains all input and output points for
00549    *    each line.  For example, for the previous image:
00550    *    (8,3)(11,3)(18,3)(21,3)(7,4)(14,4)(19,4)(22,4)...
00551    *    Note that every IO-point is a border point, but not all border
00552    *    points are IO-points.
00553    *  - Border Boints.  It contains a list of the points at the border.
00554    *    Beginning with the point at (8,3) the chain code for our example
00555    *    image is:
00556    *    (8,3)(9,3)(10,3)(11,3)(12,4)(13,4)(14,4)(15,5)(14,6)...
00557    *  - Area-Points.  It contains all points in the object.
00558    *
00559    *  @see lti::ioPoints, lti::areaPoints
00560    *
00561    *  @ingroup gAggregate
00562    *  @ingroup gShape
00563    */
00564   class borderPoints : public pointList {
00565   public:
00566     /**
00567      * default constructor creates an empty border-point-list
00568      */
00569     borderPoints();
00570 
00571     /**
00572      * create this pointList as a copy of another pointList
00573      * @param other the pointList to be copied.
00574      */
00575     borderPoints(const borderPoints& other);
00576 
00577     /**
00578      * destructor
00579      */
00580     virtual ~borderPoints();
00581 
00582     /**
00583      * returns the name of this class: "borderPoints"
00584      */
00585     const char* getTypeName() const {return "borderPoints";};
00586 
00587     /**
00588      * creates this border-point-list from the given area-point-list
00589      */
00590     borderPoints& castFrom(const areaPoints& theAreaPoints);
00591 
00592     /**
00593      * creates this io-list from the given io-point-list
00594      */
00595     borderPoints& castFrom(const ioPoints& theIOPoints);
00596 
00597    /**
00598      * creates this borderPoint-List from the given PolygonPoint-List
00599      * conecting the points with lines
00600      * @param thePolygonPoints polygon points with source data
00601      * @return a reference to this object
00602      */
00603     borderPoints& castFrom(const polygonPoints& thePolygonPoints);
00604 
00605     /**
00606      * creates this borderPoint-List from the given PolygonPoint-List
00607      * interpolating the curve with a cubicspline.
00608      * @param thePolygonPoints polygon points with source data
00609      * @param segments each space between 2 polygonPoints
00610      *        is parted in segments lines.
00611      * @return a reference to this object
00612      */
00613     borderPoints& castFrom(const polygonPoints& thePolygonPoints,
00614                            const int& segments);
00615 
00616     /**
00617      * assigment operator (alias for copy(other)).
00618      * @param other the pointList to be copied
00619      * @return a reference to the actual pointList
00620      */
00621     borderPoints& operator=(const borderPoints& other) {
00622       copy(other);
00623       return *this;
00624     };
00625 
00626     /**
00627      * generate a border-point-list from the given mask image.
00628      *
00629      * This function assumes that the mask contains JUST ONE connected
00630      * object.  To get the biggest object on the mask see the
00631      * lti::objectsFromMask functor.
00632      */
00633     bool getFromMask(const channel8& mask);
00634 
00635     /**
00636      * generate mask from border-points.
00637      *
00638      * The dimensions of the resulting mask are the smallest rectangle to
00639      * contain the point (0,0) (optional) and all points in this list, plus
00640      * 1 pixel in both width and heigth.
00641      * If the boundary of the point list is not up to date, it can
00642      * be calculated if specified in the %parameters:
00643      * @param mask The calculated mask will be stored here
00644      * @param computeBoundary If false, the internal boundary of the
00645      *    point list will be used, otherwise the boundary
00646      *    will be calculated (but NOT updated!!!).
00647      * @param exactBoundaryDimensions If true, the dimensions of the resulting
00648      *    mask will be the smallest rectangle to contain only the points in
00649      *    this list. The origin (0,0) may not be included, therefore a 1:1
00650      *    correspondence of coordinates will generally not be given.
00651      * @param keepMaskData if false, the mask will be initialized with 
00652      *                     zero before getting the area mask.  If true,
00653      *                     the previous mask data is not deleted, but
00654      *                     the mask will be resized if necessary.
00655      * @return true if successful, false otherwise.
00656      */
00657     bool generateMask(channel8& mask,
00658                       const bool computeBoundary=true,
00659                       const bool exactBoundaryDimensions=false,
00660                       const bool keepMaskData=false) const;
00661 
00662     /**
00663      * invert the direction of the border points
00664      */
00665     void invert();
00666 
00667     /**
00668      * Check consistency of border points. Border points are
00669      * consistent if the D8 distance between any two subsequent points
00670      * (with the first point being subsequent to the last) is exactly
00671      * 1, i.e. if every border point is "next to" its predecessor,
00672      * with "next to" meaning "one of the 8 neighbouring pixels in the
00673      * grid".
00674      */
00675     bool isConsistent() const;
00676 
00677   protected:
00678     inline bool inside(const point& p,const channel8& mask) {
00679       return ((p.x>=0) && (p.x<mask.columns()) &&
00680               (p.y>=0) && (p.y<mask.rows()));
00681     };
00682 
00683   };
00684 
00685   /**
00686    * Contour classes: Area-Points.
00687    *
00688    * For the explanation of the contour description in this class, see
00689    * following image:
00690    *
00691    * \code
00692    *   -- 00000000001111111111222222222233
00693    *   -- 01234567890123456789012345678901
00694    *   00 --------------------------------
00695    *   01 --------------------------------
00696    *   02 --------------------------------
00697    *   03 --------BBBB------BBBB----------
00698    *   04 -------B****BBB----B**B---------
00699    *   05 -------B*******B---B***B--------
00700    *   06 ------B*******B-----B*B---------
00701    *   07 -------B*******BBBBB**B---------
00702    *   08 ---------B*************B--------
00703    *   09 --------B**----*********B-------
00704    *   10 --------B**-----********B-------
00705    *   11 -------B**-----*******BB--------
00706    *   12 ------B**-----*******B----------
00707    *   13 ------B**-------******BB--------
00708    *   14 -----B**---------*******B-------
00709    *   15 -----B**--------*********B------
00710    *   16 ----B**-------**********BB------
00711    *   17 ---B***----*******----BB--------
00712    *   18 ----BBBBBBBBB***  --*B----------
00713    *   19 -------------BBBBBBBB-----------
00714    *   20 --------------------------------
00715    *   21 --------------------------------
00716    *   22 --------------------------------
00717    *   23 --------------------------------
00718    *
00719    *  "-" means background and the rest is part of the object.
00720    *  "B" indicates a borderpoint.
00721    *  \endcode
00722    *
00723    *  This contour class allows three representations of a contour:
00724    *  - IO-Points. It contains all input and output points for
00725    *    each line.  For example, for the previous image:
00726    *    (8,3)(11,3)(18,3)(21,3)(7,4)(14,4)(19,4)(22,4)...
00727    *    Note that every IO-point is a border point, but not all border
00728    *    points are IO-points.
00729    *  - Border Boints.  It contains a list of the points at the border.
00730    *    Beginning with the point at (8,3) the chain code for our example
00731    *    image is:
00732    *    (8,3)(9,3)(10,3)(11,3)(12,4)(13,4)(14,4)(15,5)(14,6)...
00733    *  - Area-Points.  It contains all points in the object.
00734    *
00735    *  @see lti::ioPoints, lti::borderPoints
00736    *
00737    *  @ingroup gAggregate
00738    *  @ingroup gShape
00739    */
00740   class areaPoints : public pointList {
00741   public:
00742     /**
00743      * default constructor creates an empty area-point-list
00744      */
00745     areaPoints();
00746 
00747     /**
00748      * create this pointList as a copy of another pointList
00749      * @param other the pointList to be copied.
00750      */
00751     areaPoints(const areaPoints& other);
00752 
00753     /**
00754      * destructor
00755      */
00756     virtual ~areaPoints();
00757 
00758     /**
00759      * returns the name of this class: "areaPoints"
00760      */
00761     const char* getTypeName() const {return "areaPoints";};
00762 
00763     /**
00764      * creates this area-point-list from the given border-point-list
00765      */
00766     areaPoints& castFrom(const borderPoints& theBorderPoints);
00767 
00768     /**
00769      * creates this io-list from the given io-point-list
00770      */
00771     areaPoints& castFrom(const ioPoints& theIOPoints);
00772 
00773     /**
00774      * creates this io-list from the given io-point-list
00775      */
00776     areaPoints& castFrom(const polygonPoints& theIOPoints);
00777 
00778     /**
00779      * assigment operator (alias for copy(other)).
00780      * @param other the pointList to be copied
00781      * @return a reference to the actual pointList
00782      */
00783     areaPoints& operator=(const areaPoints& other) {
00784       copy(other);
00785       return *this;
00786     };
00787 
00788     /**
00789      * generate a area-point-list from the given mask image.
00790      *
00791      * This function assumes that the mask contains JUST ONE connected
00792      * object.  To get the biggest object on the mask see the
00793      * lti::objectsFromMask functor.
00794      */
00795     bool getFromMask(const channel8& mask);
00796 
00797     /**
00798      * generate mask from area-points.
00799      *
00800      * The dimensions of the resulting mask are the smallest rectangle to
00801      * contain the point (0,0) (optional) and all points in this list, plus
00802      * 1 pixel in both width and heigth.  If the given mask is bigger than
00803      * this size, its dimensions will be kept.
00804      *
00805      * If the boundary of the point list is not up to date, it can
00806      * be calculated if specified in the %parameters:
00807      * @param mask The calculated mask will be stored here
00808      * @param computeBoundary If false, the internal boundary of the
00809      *    point list will be used, otherwise the boundary
00810      *    will be calculated (but NOT updated!!!).
00811      * @param exactBoundaryDimensions If true, the dimensions of the resulting
00812      *    mask will be the smallest rectangle to contain only the points in
00813      *    this list. The origin (0,0) may not be included, therefore a 1:1
00814      *    correspondence of coordinates will generally not be given.
00815      * @param keepMaskData if false, the mask will be initialized with 
00816      *                     zero before getting the area mask.  If true,
00817      *                     the previous mask data is not deleted, but
00818      *                     the mask will be resized if necessary.
00819      * @return true if successful, false otherwise.
00820      */
00821     bool generateMask(channel8& mask,
00822                       const bool computeBoundary=true,
00823                       const bool exactBoundaryDimensions=false,
00824                       const bool keepMaskData=false) const;
00825 
00826     /**
00827      * sort the points of this in ascending order first of y, and than of
00828      * x.
00829      */
00830     void sort();
00831 
00832     /**
00833      * Compute intersection area with a rectangle
00834      */
00835     int intersectionArea(const rectangle& rect) const;
00836   };
00837 
00838 }
00839 
00840 #include "ltiContour_inline.h"
00841 
00842 #endif

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