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_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 }
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
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:
00174 return internal::nb_connexity_c4[res];
00175 case 8:
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:
00207 return internal::nb_connexity_c4[res];
00208 case 8:
00209 return internal::nb_connexity_c8[res];
00210 default:
00211 mln_assertion(0);
00212
00213 }
00214 return 0;
00215 }
00216
00217
00218 template <typename N>
00219 template <typename I>
00220 inline
00221 bool
00222 is_simple_point<N>::check(const I& ima,
00223 const mln_psite(I)& p) const
00224 {
00225 mln_precondition(ima.is_valid());
00226 return (nb_connexity2d(ima, nbh_.foreground(), p, true) == 1)
00227 && (nb_connexity2d(ima, nbh_.background(), p, false) == 1);
00228 }
00229
00230
00231
00232
00233 template <typename N>
00234 template <typename I>
00235 inline
00236 bool
00237 is_simple_point<N>::check__(const I& ima,
00238 unsigned p) const
00239 {
00240 mln_precondition(ima.is_valid());
00241 return (nb_connexity2d__(ima, nbh_.foreground(), p, true) == 1)
00242 && (nb_connexity2d__(ima, nbh_.background(), p, false) == 1);
00243 }
00244
00245
00246 # endif // MLN_TOPO_SKELETON_INCLUDE_ONLY
00247
00248 }
00249
00250 }
00251
00252 }
00253
00254 #endif // ! MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH