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 #ifndef MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH
00027 # define MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH
00028
00033
00034 # include <mln/core/concept/image.hh>
00035 # include <mln/core/alias/point2d.hh>
00036 # include <mln/core/alias/neighb2d.hh>
00037
00038 namespace mln
00039 {
00040
00041 namespace topo
00042 {
00043
00044 namespace skeleton
00045 {
00046
00063 template <typename I, typename N>
00064 bool
00065 is_simple_point(const Image<I>& ima,
00066 const Neighborhood<N>& nbh,
00067 const mln_site(I)& p);
00068
00069
00070 # ifndef MLN_INCLUDE_ONLY
00071
00072
00073 namespace internal
00074 {
00075
00076
00077 static const unsigned char nb_connexity_c8[256] =
00078 {
00079 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1,
00080 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1,
00081 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
00082 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1,
00083
00084 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
00085 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00086 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
00087 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00088
00089 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2,
00090 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1,
00091 2, 3, 3, 3, 3, 4, 3, 3, 2, 2, 2, 2, 3, 3, 2, 2,
00092 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1,
00093
00094 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
00095 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00096 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
00097 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
00098 };
00099
00100 static const unsigned char nb_connexity_c4[256] =
00101 {
00102 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1,
00103 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
00104 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1,
00105 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
00106
00107 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2,
00108 2, 2, 3, 3, 2, 2, 2, 2, 3, 3, 4, 3, 3, 3, 3, 2,
00109 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1,
00110 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 1,
00111
00112 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1,
00113 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
00114 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1,
00115 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
00116
00117 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2,
00118 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
00119 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1,
00120 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1
00121 };
00122
00123
00124
00125 template <typename I, typename N>
00126 inline
00127 unsigned
00128 nb_connexity2d(const I& ima,
00129 const N& nbh,
00130 const mln_site(I)& p,
00131 bool object)
00132 {
00133 unsigned res = 0;
00134
00135 mln_bkd_niter(N) n(c8(), p);
00136 for_all(n)
00137 {
00138 res = (res << 1);
00139 if (ima.domain().has(n) && ima(n) == object)
00140 res = res | 1;
00141 }
00142
00143 if (nbh == c8())
00144 return nb_connexity_c8[res];
00145 else
00146 {
00147 mln_assertion(nbh == c4());
00148 return nb_connexity_c4[res];
00149 }
00150 }
00151
00152
00153 template <typename N>
00154 neighb2d
00155 complement2d(const Neighborhood<N>& nbh_)
00156 {
00157 const N& nbh = exact(nbh_);
00158 mln_precondition(nbh.is_valid());
00159 mln_precondition(nbh == c4() || nbh == c8());
00160
00161 if (nbh == c4())
00162 return c8();
00163 else
00164 return c4();
00165 }
00166
00167
00168
00169
00170 template <typename I, typename N>
00171 inline
00172 void
00173 is_simple_point_tests(const Image<I>& ima_,
00174 const Neighborhood<N>& nbh_,
00175 const mln_site(I)& p)
00176 {
00177 const I& ima = exact(ima_);
00178 const N& nbh = exact(nbh_);
00179
00180 mln_assertion(nbh == c4() || nbh == c8());
00181 mln_precondition(ima.is_valid());
00182 mln_precondition(nbh.is_valid());
00183
00184 (void) ima;
00185 (void) nbh;
00186 (void) p;
00187 }
00188
00189 }
00190
00191
00192
00193
00194
00195 namespace impl
00196 {
00197
00198 template <typename I, typename N>
00199 inline
00200 bool
00201 is_simple_point2d(const Image<I>& ima_,
00202 const Neighborhood<N>& nbh_,
00203 const point2d& p)
00204 {
00205 const I& ima = exact(ima_);
00206 const N& nbh = exact(nbh_);
00207
00208 internal::is_simple_point_tests(ima, nbh, p);
00209
00210 bool b = (internal::nb_connexity2d(ima, nbh, p, true) == 1)
00211 && (internal::nb_connexity2d(ima, internal::complement2d(nbh),
00212 p, false) == 1);
00213
00214 trace::exiting("topo::skeleton::is_simple_point2d");
00215 return b;
00216 }
00217
00218 }
00219
00220
00221
00222
00223
00224
00225 namespace internal
00226 {
00227
00228 template <typename I, typename N>
00229 inline
00230 bool
00231 is_simple_point_dispatch(const Image<I>& ima,
00232 const Neighborhood<N>& nbh,
00233 const point2d& p)
00234 {
00235 return impl::is_simple_point2d(ima, nbh, p);
00236 }
00237
00238
00239 template <typename I, typename N>
00240 inline
00241 bool
00242 is_simple_point_dispatch(const Image<I>& ima,
00243 const Neighborhood<N>& nbh,
00244 const mln_site(I)& p)
00245 {
00247 mlc_abort(I)::check();
00248 return false;
00249 }
00250
00251 }
00252
00253
00254
00255
00256
00257
00258
00259 template <typename I, typename N>
00260 inline
00261 bool
00262 is_simple_point(const Image<I>& ima,
00263 const Neighborhood<N>& nbh,
00264 const mln_site(I)& p)
00265 {
00266 trace::entering("topo::skeleton::is_simple_point2d");
00267
00268 internal::is_simple_point_tests(ima, nbh, p);
00269
00270 bool b = internal::is_simple_point_dispatch(ima, nbh, p);
00271
00272 trace::exiting("topo::skeleton::is_simple_point2d");
00273 return b;
00274 }
00275
00276
00277 # endif // MLN_TOPO_SKELETON_INCLUDE_ONLY
00278
00279 }
00280
00281 }
00282
00283 }
00284
00285 #endif // ! MLN_TOPO_SKELETON_IS_SIMPLE_POINT_HH