[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
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> <<a href="contourcirculator_8hxx-source.html">vigra/contourcirculator.hxx</a>><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) |
html generated using doxygen and Python
|