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_BREADTH_FIRST_THINNING_HH
00027 # define MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH
00028
00032
00033 # include <algorithm>
00034
00035 # include <mln/core/routine/duplicate.hh>
00036
00037 # include <mln/core/concept/image.hh>
00038 # include <mln/core/concept/neighborhood.hh>
00039
00040 # include <mln/core/site_set/p_set.hh>
00041
00042 # include <mln/fun/p2b/tautology.hh>
00043
00044 namespace mln
00045 {
00046
00047 namespace topo
00048 {
00049
00050 namespace skeleton
00051 {
00052
00067 template <typename I, typename N, typename F, typename G, typename H>
00068 mln_concrete(I)
00069 breadth_first_thinning(const Image<I>& input,
00070 const Neighborhood<N>& nbh,
00071 Function_v2b<F>& is_simple,
00072 G detach,
00073 const Function_v2b<H>& constraint);
00074
00075
00088 template <typename I, typename N, typename F, typename G>
00089 mln_concrete(I)
00090 breadth_first_thinning(const Image<I>& input,
00091 const Neighborhood<N>& nbh,
00092 Function_v2b<F>& is_simple,
00093 G detach);
00094
00095
00096 # ifndef MLN_INCLUDE_ONLY
00097
00098 template <typename I, typename N, typename F, typename G, typename H>
00099 inline
00100 mln_concrete(I)
00101 breadth_first_thinning(const Image<I>& input_,
00102 const Neighborhood<N>& nbh_,
00103 Function_v2b<F>& is_simple_,
00104 G detach,
00105 const Function_v2b<H>& constraint_)
00106 {
00107 const I& input = exact(input_);
00108 const N& nbh = exact(nbh_);
00109 F& is_simple = exact(is_simple_);
00110 const H& constraint = exact(constraint_);
00111
00112 mln_concrete(I) output = duplicate(input);
00113
00114 is_simple.set_image(output);
00115
00116 typedef mln_psite(I) psite;
00117 typedef p_set<psite> set_t;
00118 set_t set;
00119
00120 mln_piter(I) p_(output.domain());
00121 for_all(p_)
00122 {
00123
00124
00125
00126
00127
00128 psite p = p_;
00129 if (output(p) && constraint(p) && is_simple(p))
00130 set.insert(p);
00131 }
00132
00133 while (!set.is_empty())
00134 {
00135 set_t next_set;
00136
00137 mln_piter(set_t) ps(set);
00138 for_all(ps)
00139 {
00140
00141 psite p = ps;
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 if (constraint(p) && is_simple(p))
00152 {
00153 detach(p, output);
00154 mln_niter(N) n_(nbh, p);
00155 for_all(n_)
00156 {
00157
00158 psite n = n_;
00159 if (output.domain().has(n)
00160 && output(n) && constraint(n) && is_simple(n))
00161 next_set.insert(n);
00162 }
00163 }
00164 }
00165 set.clear();
00166 std::swap(set, next_set);
00167 }
00168 return output;
00169 }
00170
00171
00172 template <typename I, typename N, typename F, typename G>
00173 inline
00174 mln_concrete(I)
00175 breadth_first_thinning(const Image<I>& input,
00176 const Neighborhood<N>& nbh,
00177 Function_v2b<F>& is_simple,
00178 G detach)
00179 {
00180 return breadth_first_thinning(input, nbh, is_simple, detach,
00181 fun::p2b::tautology());
00182 }
00183
00184 # endif // MLN_INCLUDE_ONLY
00185
00186 }
00187
00188 }
00189
00190 }
00191
00192 #endif // ! MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH