Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development 00002 // Laboratory (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_IS_SIMPLE_2D_HH 00028 # define MLN_TOPO_IS_SIMPLE_2D_HH 00029 00034 00038 00039 00040 #include <mln/core/concept/image.hh> 00041 #include <mln/core/concept/neighborhood.hh> 00042 00043 #include <mln/core/alias/point2d.hh> 00044 #include <mln/core/alias/neighb2d.hh> 00045 00046 00047 namespace mln 00048 { 00049 00050 namespace topo 00051 { 00052 00065 template <typename N> 00066 struct is_simple_2d_t 00067 { 00068 00069 is_simple_2d_t(const Neighborhood<N>& nbh); 00070 00071 template <typename I> 00072 bool check(const I& ima, const mln_psite(I)& p) const; 00073 00074 template <typename I> 00075 bool check__(const I& ima, unsigned p) const; 00076 00077 template <typename I, typename N2> 00078 unsigned nb_connectivity2d(const I&, const N2& nbh, 00079 const mln_psite(I)& p, bool object) const; 00080 template <typename I, typename N2> 00081 unsigned nb_connectivity2d__(const I&, const N2& nbh, 00082 unsigned p, bool object) const; 00083 00084 protected: 00085 const N& nbh_; 00086 }; 00087 00088 00089 00090 # ifndef MLN_INCLUDE_ONLY 00091 00092 namespace internal 00093 { 00094 00095 static const unsigned char connectivity_number_c8[256] = 00096 { 00097 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 00098 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 00099 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00100 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 00101 00102 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00103 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 00104 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00105 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 00106 00107 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 00108 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 00109 2, 3, 3, 3, 3, 4, 3, 3, 2, 2, 2, 2, 3, 3, 2, 2, 00110 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 00111 00112 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00113 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 00114 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 00115 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 00116 }; 00117 00118 00119 static const unsigned char connectivity_number_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 mln::topo::internal 00143 00144 template <typename N> 00145 is_simple_2d_t<N>::is_simple_2d_t(const Neighborhood<N>& nbh) 00146 : nbh_(exact(nbh)) 00147 { 00148 mln_precondition(nbh_.is_valid()); 00149 } 00150 00151 00152 00153 template <typename N> 00154 template <typename I, typename N2> 00155 unsigned 00156 is_simple_2d_t<N>::nb_connectivity2d(const I& ima, const N2& nbh, 00157 const mln_psite(I)& p, bool b) const 00158 { 00159 mln_precondition(ima.is_valid()); 00160 mln_precondition(nbh.is_valid()); 00161 00162 unsigned res = 0; 00163 00164 // Note: fwd here but bkd in is_simple_point.hh... 00165 mln_fwd_niter(N2) n(c8(), p); 00166 for_all(n) 00167 { 00168 res = (res << 1); 00169 if (ima.has(n) && ima(n) == b) 00170 res = res | 1; 00171 } 00172 00173 switch (nbh.size()) 00174 { 00175 case 4: // C4 00176 return internal::connectivity_number_c4[res]; 00177 case 8: // C8 00178 return internal::connectivity_number_c8[res]; 00179 default: 00180 mln_assertion(0); 00181 00182 } 00183 00184 return 0; 00185 } 00186 00187 00188 template <typename N> 00189 template <typename I, typename N2> 00190 unsigned 00191 is_simple_2d_t<N>::nb_connectivity2d__(const I& ima, const N2& nbh, 00192 unsigned p, bool b) const 00193 { 00194 mln_precondition(ima.is_valid()); 00195 mln_precondition(nbh.is_valid()); 00196 00197 unsigned res = 0; 00198 00199 static util::array<int> 00200 noffset = mln::offsets_wrt(ima, c8()); 00201 00202 for (unsigned i = 0; i < noffset.nelements(); ++i) 00203 { 00204 res = (res << 1); 00205 if (ima.element(p + noffset[i]) == b) 00206 res = res | 1; 00207 } 00208 00209 switch (nbh.size()) 00210 { 00211 case 4: // C4 00212 return internal::connectivity_number_c4[res]; 00213 case 8: // C8 00214 return internal::connectivity_number_c8[res]; 00215 default: 00216 mln_assertion(0); 00217 00218 } 00219 00220 return 0; 00221 } 00222 00223 00224 template <typename N> 00225 template <typename I> 00226 inline 00227 bool 00228 is_simple_2d_t<N>::check(const I& ima, const mln_psite(I)& p) const 00229 { 00230 mln_precondition(ima.is_valid()); 00231 return (nb_connectivity2d(ima, nbh_.foreground(), p, true) == 1) // Consider neighbor. 00232 && (nb_connectivity2d(ima, nbh_.background(), p, false) == 1); // Consider complement neighbor. 00233 } 00234 00235 00236 00237 00238 template <typename N> 00239 template <typename I> 00240 inline 00241 bool 00242 is_simple_2d_t<N>::check__(const I& ima, unsigned p) const 00243 { 00244 mln_precondition(ima.is_valid()); 00245 return (nb_connectivity2d__(ima, nbh_.foreground(), p, true) == 1) // Consider neighbor 00246 && (nb_connectivity2d__(ima, nbh_.background(), p, false) == 1); // Consider complement neighbor. 00247 } 00248 00249 00250 00251 # endif // MLN_INCLUDE_ONLY 00252 00253 } // end of namespace mln::topo 00254 00255 } // end of namespace mln 00256 00257 #endif // ! MLN_TOPO_IS_SIMPLE_2D_HH