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