[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]

| vigra/contourcirculator.hxx |
--- | --- | ---

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
    00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
    00005 /*                                                                      */
    00006 /*    This file is part of the VIGRA computer vision library.           */
    00007 /*    ( Version 1.3.2, Jan 27 2005 )                                    */
    00008 /*    You may use, modify, and distribute this software according       */
    00009 /*    to the terms stated in the LICENSE file included in               */
    00010 /*    the VIGRA distribution.                                           */
    00011 /*                                                                      */
    00012 /*    The VIGRA Website is                                              */
    00013 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
    00014 /*    Please direct questions, bug reports, and contributions to        */
    00015 /*        koethe@informatik.uni-hamburg.de                              */
    00016 /*                                                                      */
    00017 /*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
    00018 /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
    00019 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
    00020 /*                                                                      */
    00021 /************************************************************************/
    00022
    00023
    00024 #ifndef VIGRA_CONTOURCIRCULATOR_HXX
    00025 #define VIGRA_CONTOURCIRCULATOR_HXX
    00026
    00027 #include <vigra/pixelneighborhood.hxx>
    00028
    00029 namespace vigra
    00030 {
    00031
    00032 /** \addtogroup ImageIteratorAdapters
    00033  */
    00034 //@{
    00035
    00036 /********************************************************/
    00037 /*                                                      */
    00038 /*                CrackContourCirculator                */
    00039 /*                                                      */
    00040 /********************************************************/
    00041
    00042 /** \brief Circulator that walks around a given region.
    00043
    00044     The circulator follows the <em>crack contour</em> of a given region.
    00045     Here, a region is an 8-connected component of pixels with the same
    00046     value, such as the regions in a label image.
    00047     The crack contour is located between the inside and outside
    00048     pixels, that is "on the crack" between the region and the background.
    00049     Thus, the circulator moves from pixel corner to pixel corner. By definition,
    00050     the first corner (were the circulator was initialized) gets the
    00051     coordinate (0,0), and calls to <tt>*circulator</tt> return the distance
    00052     of the current corner to the initial one.
    00053
    00054     The circulator can be used to calculate the area of the region (in pixels):
    00055
    00056     \code
    00057     ImageIterator region_anchor = ...;
    00058     int area = 0;
    00059
    00060     // calculate area from following the crack contour of the region
    00061     CrackContourCirculator<ImageIterator> crack(region_anchor);
    00062     CrackContourCirculator<ImageIterator> crackend(crack);
    00063     do
    00064     {
    00065         area += crack.diff().x * crack.pos().y -
    00066                 crack.diff().y * crack.pos().x;
    00067     }
    00068     while(++crack != crackend);
    00069
    00070     area /= 2;
    00071     std::cout << "Area of region " << *region_anchor << ": " << area << std::endl;
    00072     \endcode
    00073
    00074     <b>\#include</b> "<a href="contourcirculator_8hxx-source.html">vigra/contourcirculator.hxx</a>"<br>
    00075     Namespace: vigra
    00076 */
    00077 template <class IMAGEITERATOR>
    00078 class CrackContourCirculator
    00079 {
    00080     typedef NeighborhoodCirculator<IMAGEITERATOR, EightNeighborCode>
    00081             NEIGHBORHOODCIRCULATOR;
    00082     typedef typename IMAGEITERATOR::value_type label_type;
    00083
    00084 protected:
    00085     NEIGHBORHOODCIRCULATOR neighborCirc_;
    00086     label_type label_;
    00087     Point2D pos_;
    00088
    00089 public:
    00090         /** the circulator's value type
    00091         */
    00092     typedef Point2D value_type;
    00093
    00094         /** the circulator's reference type (return type of <TT>*circ</TT>)
    00095         */
    00096     typedef Point2D const & reference;
    00097
    00098         /** the circulator's pointer type (return type of <TT>operator-></TT>)
    00099         */
    00100     typedef Point2D const * pointer;
    00101
    00102         /** the circulator tag
    00103         */
    00104     typedef forward_circulator_tag iterator_category;
    00105
    00106         /** Initialize the circulator for a given region.
    00107
    00108             The image iterator <tt>in_the_region</tt> must refer
    00109             to a boundary pixel of the region to be analysed. The
    00110             direction code <tt>dir</tt> must point to a pixel outside the
    00111             region (the default assumes that the pixel left of the
    00112             given region pixel belongs to the background).
    00113             The first corner of the crack contour is the corner to the
    00114             right of this direction (i.e. the north west corner of
    00115             the region pixel, if the direction was West).
    00116         */
    00117     CrackContourCirculator(IMAGEITERATOR const & in_the_region,
    00118                            vigra::FourNeighborCode::Direction dir = vigra::FourNeighborCode::West)
    00119         : neighborCirc_(in_the_region, EightNeighborCode::code(dir)),
    00120           label_(*(neighborCirc_.center())),
    00121           pos_(0, 0)
    00122     {
    00123         neighborCirc_.turnLeft();
    00124     }
    00125
    00126         /** Move to the next crack corner of the contour (pre-increment).
    00127         */
    00128     CrackContourCirculator & operator++()
    00129     {
    00130         pos_ += neighborCirc_.diff();
    00131
    00132         neighborCirc_--;
    00133
    00134         if(*neighborCirc_ == label_)
    00135         {
    00136             neighborCirc_.moveCenterToNeighbor(); // TODO: simplify moveCenterToNeighbor()s
    00137             --neighborCirc_;
    00138         }
    00139         else
    00140         {
    00141             neighborCirc_.moveCenterToNeighbor(); // jump out
    00142             neighborCirc_ += 3;
    00143             if(*neighborCirc_ == label_)
    00144             {
    00145                 neighborCirc_.moveCenterToNeighbor();
    00146                 neighborCirc_.turnRight();
    00147             }
    00148             else
    00149             {
    00150                 neighborCirc_.moveCenterToNeighbor();
    00151                 neighborCirc_.turnLeft();
    00152                 neighborCirc_.moveCenterToNeighbor();
    00153                 neighborCirc_.turnRight();
    00154             }
    00155         }
    00156
    00157         return *this;
    00158     }
    00159
    00160         /** Move to the next crack corner of the contour (post-increment).
    00161         */
    00162     CrackContourCirculator operator++(int)
    00163     {
    00164         CrackContourCirculator ret(*this);
    00165         ++(*this);
    00166         return ret;
    00167     }
    00168
    00169         /** equality
    00170         */
    00171     bool operator==(CrackContourCirculator const & o) const
    00172     {
    00173         return neighborCirc_ == o.neighborCirc_;
    00174     }
    00175
    00176         /** inequality
    00177         */
    00178     bool operator!=(CrackContourCirculator const & o) const
    00179     {
    00180         return neighborCirc_ != o.neighborCirc_;
    00181     }
    00182
    00183         /** Get the coordinate of the current corner
    00184             (relative to the first corner).
    00185         */
    00186     reference pos() const
    00187         { return pos_; }
    00188
    00189         /** Equivalent to pos()
    00190         */
    00191     reference operator*() const
    00192         { return pos_; }
    00193
    00194         /** Access member of the current coordinate.
    00195         */
    00196     pointer operator->() const
    00197         { return &pos_; }
    00198
    00199         /** Access pixel to the right of the crack edge (outside of
    00200          * the region bounded by the crack contour we walk on). Note
    00201          * that after operator++, the iterator can still point to the
    00202          * same pixel (looking from another direction now).
    00203          */
    00204     IMAGEITERATOR outerPixel() const
    00205         { return NEIGHBORHOODCIRCULATOR(neighborCirc_).turnRight().base(); }
    00206
    00207         /** Get the offset from the current corner of the contour
    00208             to the next one.
    00209         */
    00210     Diff2D const & diff() const
    00211         { return neighborCirc_.diff(); }
    00212 };
    00213
    00214 //@}
    00215
    00216 } // namespace vigra
    00217
    00218 #endif /* VIGRA_CONTOURCIRCULATOR_HXX */

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.3.2 (27 Jan 2005)