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 fun::p2b::tautology());
00075
00076
00077 # ifndef MLN_INCLUDE_ONLY
00078
00079 template <typename I, typename N, typename F, typename G, typename H>
00080 inline
00081 mln_concrete(I)
00082 breadth_first_thinning(const Image<I>& input_,
00083 const Neighborhood<N>& nbh_,
00084 Function_v2b<F>& is_simple_,
00085 G detach,
00086 const Function_v2b<H>& constraint_)
00087 {
00088 const I& input = exact(input_);
00089 const N& nbh = exact(nbh_);
00090 F& is_simple = exact(is_simple_);
00091 const H& constraint = exact(constraint_);
00092
00093 I output = duplicate(input);
00094
00095 is_simple.set_image(output);
00096
00097 typedef mln_psite(I) psite;
00098 typedef p_set<psite> set_t;
00099 set_t set;
00100
00101 mln_piter(I) p_(output.domain());
00102 for_all(p_)
00103 {
00104
00105
00106
00107
00108
00109 psite p = p_;
00110 if (output(p) && constraint(p) && is_simple(p))
00111 set.insert(p);
00112 }
00113
00114 while (!set.is_empty())
00115 {
00116 set_t next_set;
00117
00118
00119
00120
00121
00122 # if 0
00123 mln_piter(set_t) ps(set);
00124 for_all(ps);
00125 {
00126
00127 psite p = p_;
00128 # endif
00129 for (unsigned i = 0; i < set.nsites(); ++i)
00130 {
00131 psite p = set[i];
00132
00133
00134
00135
00136
00137 if (constraint(p) && is_simple(p))
00138 {
00139 detach(p, output);
00140 mln_niter(N) n(nbh, p);
00141 for_all(n)
00142 if (output.domain().has(n)
00143 && output(n) && constraint(p) && is_simple(n))
00144 next_set.insert(n);
00145 }
00146 }
00147 set.clear();
00148 std::swap(set, next_set);
00149 }
00150 return output;
00151 }
00152
00153 # endif // MLN_INCLUDE_ONLY
00154
00155 }
00156
00157 }
00158
00159 }
00160
00161 #endif // ! MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH