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

details vigra/contourcirculator.hxx VIGRA

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.3, Aug 18 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.3 (18 Aug 2005)