Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2009, 2011 EPITA Research and Development Laboratory 00002 // (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH 00028 # define MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH 00029 00037 00038 # include <mln/core/concept/image.hh> 00039 # include <mln/core/alias/point2d.hh> 00040 # include <mln/core/alias/neighb2d.hh> 00041 00042 namespace mln 00043 { 00044 00045 namespace topo 00046 { 00047 00048 namespace skeleton 00049 { 00050 00067 template <typename N> 00068 struct is_simple_point 00069 { 00070 00071 is_simple_point(const Neighborhood<N>& nbh); 00072 00073 template <typename I> 00074 bool check(const I& ima, const mln_psite(I)& p) const; 00075 template <typename I> 00076 bool check__(const I& ima, unsigned p) const; 00077 00078 protected: 00079 const N& nbh_; 00080 bool is_c8_; 00081 00082 template <typename I, typename N2> 00083 unsigned nb_connexity2d(const I&, const N2 nbh, 00084 const mln_psite(I)& p, bool object) const; 00085 template <typename I, typename N2> 00086 unsigned nb_connexity2d__(const I&, const N2 nbh, 00087 unsigned p, bool object) const; 00088 00089 }; 00090 00091 # ifndef MLN_INCLUDE_ONLY 00092 00093 00094 namespace internal 00095 { 00096 static const unsigned char nb_connexity_c8[256] = 00097 { 00098 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 00099 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 00100 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00101 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 00102 00103 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00104 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 00105 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00106 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 00107 00108 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 00109 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 00110 2, 3, 3, 3, 3, 4, 3, 3, 2, 2, 2, 2, 3, 3, 2, 2, 00111 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 00112 00113 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00114 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 00115 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00116 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 00117 }; 00118 00119 static const unsigned char nb_connexity_c4[256] = 00120 { 00121 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 00122 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, 00123 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 00124 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, 00125 00126 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2, 00127 2, 2, 3, 3, 2, 2, 2, 2, 3, 3, 4, 3, 3, 3, 3, 2, 00128 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 00129 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 1, 00130 00131 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 00132 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, 00133 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 00134 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, 00135 00136 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2, 00137 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, 00138 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 00139 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1 00140 }; 00141 00142 } // end of namespace internal 00143 00144 template <typename N> 00145 is_simple_point<N>::is_simple_point(const Neighborhood<N>& nbh) 00146 : nbh_(exact(nbh)) 00147 { 00148 mln_precondition(nbh_.is_valid()); 00149 } 00150 00151 00152 template <typename N> 00153 template <typename I, typename N2> 00154 unsigned 00155 is_simple_point<N>::nb_connexity2d(const I& ima, 00156 const N2 nbh, 00157 const mln_psite(I)& p, 00158 bool object) const 00159 { 00160 unsigned res = 0; 00161 00162 // Note: bkd here but fwd in is_simple_2d.hh... 00163 mln_bkd_niter(N2) n(c8(), p); 00164 for_all(n) 00165 { 00166 res = (res << 1); 00167 if (ima.domain().has(n) && ima(n) == object) 00168 res = res | 1; 00169 } 00170 00171 switch (nbh.size()) 00172 { 00173 case 4: // C4 00174 return internal::nb_connexity_c4[res]; 00175 case 8: // C8 00176 return internal::nb_connexity_c8[res]; 00177 default: 00178 mln_assertion(0); 00179 00180 } 00181 } 00182 00183 00184 template <typename N> 00185 template <typename I, typename N2> 00186 unsigned 00187 is_simple_point<N>::nb_connexity2d__(const I& ima, 00188 const N2 nbh, 00189 unsigned p, 00190 bool object) const 00191 { 00192 unsigned res = 0; 00193 00194 static util::array<int> 00195 noffset = mln::offsets_wrt(ima, c8()); 00196 00197 for (int i = noffset.nelements() - 1; i >= 0; --i) 00198 { 00199 res = (res << 1); 00200 if (ima.element(p + noffset[i]) == object) 00201 res = res | 1; 00202 } 00203 00204 switch (nbh.size()) 00205 { 00206 case 4: // C4 00207 return internal::nb_connexity_c4[res]; 00208 case 8: // C8 00209 return internal::nb_connexity_c8[res]; 00210 default: 00211 mln_assertion(0); 00212 } 00213 return 0; 00214 } 00215 00216 00217 template <typename N> 00218 template <typename I> 00219 inline 00220 bool 00221 is_simple_point<N>::check(const I& ima, 00222 const mln_psite(I)& p) const 00223 { 00224 mln_precondition(ima.is_valid()); 00225 return (nb_connexity2d(ima, nbh_.foreground(), p, true) == 1) // Consider neighbor. 00226 && (nb_connexity2d(ima, nbh_.background(), p, false) == 1); // Consider complement neighbor. 00227 } 00228 00229 00230 00231 00232 template <typename N> 00233 template <typename I> 00234 inline 00235 bool 00236 is_simple_point<N>::check__(const I& ima, 00237 unsigned p) const 00238 { 00239 mln_precondition(ima.is_valid()); 00240 return (nb_connexity2d__(ima, nbh_.foreground(), p, true) == 1) // Consider neighbor 00241 && (nb_connexity2d__(ima, nbh_.background(), p, false) == 1); // Consider complement neighbor. 00242 } 00243 00244 00245 # endif // MLN_TOPO_SKELETON_INCLUDE_ONLY 00246 00247 } // end of namespace mln::topo::skeleton 00248 00249 } // end of namespace mln::topo 00250 00251 } // end of namespace mln 00252 00253 #endif // ! MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH