[ 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.4.0, Dec 21 2005 )                                    */
00008 /*    The VIGRA Website is                                              */
00009 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
00010 /*    Please direct questions, bug reports, and contributions to        */
00011 /*        koethe@informatik.uni-hamburg.de          or                  */
00012 /*        vigra@kogs1.informatik.uni-hamburg.de                         */
00013 /*                                                                      */
00014 /*    Permission is hereby granted, free of charge, to any person       */
00015 /*    obtaining a copy of this software and associated documentation    */
00016 /*    files (the "Software"), to deal in the Software without           */
00017 /*    restriction, including without limitation the rights to use,      */
00018 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
00019 /*    sell copies of the Software, and to permit persons to whom the    */
00020 /*    Software is furnished to do so, subject to the following          */
00021 /*    conditions:                                                       */
00022 /*                                                                      */
00023 /*    The above copyright notice and this permission notice shall be    */
00024 /*    included in all copies or substantial portions of the             */
00025 /*    Software.                                                         */
00026 /*                                                                      */
00027 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
00028 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
00029 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
00030 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
00031 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
00032 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
00033 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
00034 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
00035 /*                                                                      */
00036 /************************************************************************/
00037 
00038 
00039 #ifndef VIGRA_CONTOURCIRCULATOR_HXX
00040 #define VIGRA_CONTOURCIRCULATOR_HXX
00041 
00042 #include <vigra/pixelneighborhood.hxx>
00043 
00044 namespace vigra
00045 {
00046 
00047 /** \addtogroup ImageIteratorAdapters
00048  */
00049 //@{
00050 
00051 /********************************************************/
00052 /*                                                      */
00053 /*                CrackContourCirculator                */
00054 /*                                                      */
00055 /********************************************************/
00056 
00057 /** \brief Circulator that walks around a given region.
00058 
00059     The circulator follows the <em>crack contour</em> of a given region.
00060     Here, a region is an 8-connected component of pixels with the same
00061     value, such as the regions in a label image.
00062     The crack contour is located between the inside and outside
00063     pixels, that is "on the crack" between the region and the background.
00064     Thus, the circulator moves from pixel corner to pixel corner. By definition,
00065     the first corner (where the circulator was initialized) gets the
00066     coordinate (0,0), and calls to <tt>*circulator</tt> return the distance
00067     of the current corner to the initial one.
00068 
00069     The circulator can be used to calculate the area of a region (in pixels):
00070 
00071     \code
00072     // start with a pixel within the region, whose left neighbor is outside
00073     // (see CrackContourCirculator constructor)
00074     ImageIterator region_anchor = ...;
00075     int area = 0;
00076 
00077     // calculate area from following the crack contour of the region
00078     CrackContourCirculator<ImageIterator> crack(region_anchor);
00079     CrackContourCirculator<ImageIterator> crackend(crack);
00080     do
00081     {
00082         area += crack.diff().x * crack.pos().y -
00083                 crack.diff().y * crack.pos().x;
00084     }
00085     while(++crack != crackend);
00086 
00087     area /= 2;
00088     std::cout << "Area of region " << *region_anchor << ": " << area << std::endl;
00089     \endcode
00090 
00091     <b>\#include</b> "<a href="contourcirculator_8hxx-source.html">vigra/contourcirculator.hxx</a>"<br>
00092     Namespace: vigra
00093 */
00094 template <class IMAGEITERATOR>
00095 class CrackContourCirculator
00096 {
00097     typedef NeighborhoodCirculator<IMAGEITERATOR, EightNeighborCode>
00098             NEIGHBORHOODCIRCULATOR;
00099     typedef typename IMAGEITERATOR::value_type label_type;
00100 
00101 protected:
00102     NEIGHBORHOODCIRCULATOR neighborCirc_;
00103     label_type label_;
00104     Point2D pos_;
00105 
00106     CrackContourCirculator(NEIGHBORHOODCIRCULATOR const & circ)
00107         : neighborCirc_(circ),
00108           label_(*(circ.center())),
00109           pos_(0, 0)
00110     {}
00111 
00112 public:
00113         /** the circulator's value type
00114         */
00115     typedef Point2D value_type;
00116 
00117         /** the circulator's reference type (return type of <TT>*circ</TT>)
00118         */
00119     typedef Point2D const & reference;
00120 
00121         /** the circulator's pointer type (return type of <TT>operator-></TT>)
00122         */
00123     typedef Point2D const * pointer;
00124 
00125         /** the circulator tag
00126         */
00127     typedef forward_circulator_tag iterator_category;
00128 
00129         /** Initialize the circulator for a given region.
00130 
00131             The image iterator <tt>in_the_region</tt> must refer
00132             to a boundary pixel of the region to be analysed. The
00133             direction code <tt>dir</tt> must point to a pixel outside the
00134             region (the default assumes that the pixel left of the
00135             given region pixel belongs to the background).
00136             The first corner of the crack contour is the corner to the
00137             right of this direction (i.e. the north west corner of
00138             the region pixel, if the direction was West).
00139         */
00140     CrackContourCirculator(IMAGEITERATOR const & in_the_region,
00141                            vigra::FourNeighborCode::Direction dir = vigra::FourNeighborCode::West)
00142         : neighborCirc_(in_the_region, EightNeighborCode::code(dir)),
00143           label_(*in_the_region),
00144           pos_(0, 0)
00145     {
00146         neighborCirc_.turnLeft();
00147     }
00148 
00149         /** Move to the next crack corner of the contour (pre-increment).
00150         */
00151     CrackContourCirculator & operator++()
00152     {
00153         pos_ += neighborCirc_.diff();
00154 
00155         neighborCirc_--;
00156 
00157         if(*neighborCirc_ == label_)
00158         {
00159             neighborCirc_.moveCenterToNeighbor(); // TODO: simplify moveCenterToNeighbor()s
00160             --neighborCirc_;
00161         }
00162         else
00163         {
00164             neighborCirc_.moveCenterToNeighbor(); // jump out
00165             neighborCirc_ += 3;
00166             if(*neighborCirc_ == label_)
00167             {
00168                 neighborCirc_.moveCenterToNeighbor();
00169                 neighborCirc_.turnRight();
00170             }
00171             else
00172             {
00173                 neighborCirc_.moveCenterToNeighbor();
00174                 neighborCirc_.turnLeft();
00175                 neighborCirc_.moveCenterToNeighbor();
00176                 neighborCirc_.turnRight();
00177             }
00178         }
00179 
00180         return *this;
00181     }
00182 
00183         /** Move to the next crack corner of the contour (post-increment).
00184         */
00185     CrackContourCirculator operator++(int)
00186     {
00187         CrackContourCirculator ret(*this);
00188         ++(*this);
00189         return ret;
00190     }
00191 
00192         /** equality
00193         */
00194     bool operator==(CrackContourCirculator const & o) const
00195     {
00196         return neighborCirc_ == o.neighborCirc_;
00197     }
00198 
00199         /** inequality
00200         */
00201     bool operator!=(CrackContourCirculator const & o) const
00202     {
00203         return neighborCirc_ != o.neighborCirc_;
00204     }
00205 
00206         /** Get the coordinate of the current corner
00207             (relative to the first corner).
00208         */
00209     reference pos() const
00210         { return pos_; }
00211 
00212         /** Equivalent to pos()
00213         */
00214     reference operator*() const
00215         { return pos_; }
00216 
00217         /** Access member of the current coordinate.
00218         */
00219     pointer operator->() const
00220         { return &pos_; }
00221 
00222         /** Access pixel to the right of the crack edge (outside of
00223          * the region bounded by the crack contour we walk on). Note
00224          * that after operator++, the iterator can still point to the
00225          * same pixel (looking from another direction now).
00226          */
00227     IMAGEITERATOR outerPixel() const
00228         { return NEIGHBORHOODCIRCULATOR(neighborCirc_).turnRight().base(); }
00229 
00230         /** Get the offset from the current corner of the contour
00231             to the next one.
00232         */
00233     Diff2D const & diff() const
00234         { return neighborCirc_.diff(); }
00235 };
00236 
00237 //@}
00238 
00239 } // namespace vigra
00240 
00241 #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.4.0 (21 Dec 2005)