00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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 }
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
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:
00176 return internal::connectivity_number_c4[res];
00177 case 8:
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:
00212 return internal::connectivity_number_c4[res];
00213 case 8:
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)
00232 && (nb_connectivity2d(ima, nbh_.background(), p, false) == 1);
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)
00246 && (nb_connectivity2d__(ima, nbh_.background(), p, false) == 1);
00247 }
00248
00249
00250
00251 # endif // MLN_INCLUDE_ONLY
00252
00253 }
00254
00255 }
00256
00257 #endif // ! MLN_TOPO_IS_SIMPLE_2D_HH