vigra - vigra/contourcirculator.hxx Source File

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

vigra/contourcirculator.hxx |

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