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