[ 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.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) |
html generated using doxygen and Python
|