[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | 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.6.0, Aug 13 2008 )                                    */
    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 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00012 /*        vigra@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 "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 (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python VIGRA 1.6.0 (13 Aug 2008)