27 #ifndef MLN_MORPHO_RECONSTRUCTION_BY_DILATION_UNION_FIND_HH
28 # define MLN_MORPHO_RECONSTRUCTION_BY_DILATION_UNION_FIND_HH
35 # include <mln/core/concept/image.hh>
36 # include <mln/core/concept/neighborhood.hh>
37 # include <mln/data/fill.hh>
38 # include <mln/data/compare.hh>
39 # include <mln/data/sort_psites.hh>
48 namespace reconstruction
55 template <
typename I,
typename J,
typename N>
57 union_find(const Image<I>& f, const Image<J>& g,
58 const Neighborhood<N>& nbh);
61 # ifndef MLN_INCLUDE_ONLY
69 template <
typename I,
typename J,
typename N>
72 union_find_tests(
const Image<I>& f_,
const Image<J>& g_,
73 const Neighborhood<N>& nbh_)
75 const I& f = exact(f_);
76 const J& g = exact(g_);
77 const N& nbh = exact(nbh_);
79 mln_precondition(f.is_valid());
80 mln_precondition(g.is_valid());
81 mln_precondition(nbh.is_valid());
83 mln_precondition(f.domain() == g.domain());
84 mln_precondition(f <= g);
96 template <
typename Par>
98 mln_site(Par) find_root(Par& parent, mln_site(Par) x)
103 return parent(x) = find_root(parent, parent(x));
118 template <
typename I,
typename J,
typename N>
121 union_find(const Image<I>& f_, const Image<J>& g_,
122 const Neighborhood<N>& nbh_)
124 trace::entering(
"morpho::reconstruction::by_dilation::impl::generic::union_find");
126 const I& f = exact(f_);
127 const J& g = exact(g_);
128 const N& nbh = exact(nbh_);
130 internal::union_find_tests(f, g, nbh);
133 typedef mln_site(I) P;
134 typedef mln_value(I) V;
138 mln_ch_value(I,
bool) deja_vu;
139 mln_ch_value(I, P) parent;
140 mln_concrete(I) output;
155 for (
unsigned i = 0; i < s.nsites(); ++i)
159 mln_niter(N) n(nbh, p);
167 if (f.domain().has(n) && deja_vu(n))
170 P r = internal::find_root(parent, n);
173 if (g(r) == g(p) || g(p) >= output(r))
176 if (output(r) > output(p))
177 output(p) = output(r);
180 output(p) = mln_max(V);
190 for (
int i = s.nsites() - 1; i >= 0; --i)
195 if (output(p) == mln_max(V))
199 output(p) = output(parent(p));
203 mln_postcondition(output >= f);
204 mln_postcondition(output <= g);
206 trace::exiting(
"morpho::reconstruction::by_dilation::impl::generic::union_find");
221 template <
typename I,
typename J,
typename N>
224 union_find_dispatch(trait::image::kind::logic,
225 const Image<I>& f, const Image<J>& g,
226 const Neighborhood<N>& nbh)
234 << __FILE__ <<
":" << __LINE__ <<
": error:\n"
235 "mln::morpho::reconstruction::by_dilation::internal::\n"
236 " union_find_dispatch(mln::trait::image::kind::logic,\n"
237 " const mln::Image<I>&,\n"
238 " const mln::Image<J>&,\n"
239 " const mln::Neighborhood<N>&)\n"
245 template <
typename I,
typename J,
typename N>
248 union_find_dispatch(trait::image::kind::any,
249 const Image<I>& f, const Image<J>& g,
250 const Neighborhood<N>& nbh)
252 return impl::generic::union_find(f, g, nbh);
255 template <
typename I,
typename J,
typename N>
258 union_find_dispatch(const Image<I>& f, const Image<J>& g,
259 const Neighborhood<N>& nbh)
261 return union_find_dispatch(mln_trait_image_kind(I)(),
270 template <
typename I,
typename J,
typename N>
273 union_find(const Image<I>& f, const Image<J>& g,
274 const Neighborhood<N>& nbh)
276 trace::entering(
"morpho::reconstruction::by_dilation::union_find");
278 internal::union_find_tests(f, g, nbh);
280 mln_concrete(I) output;
281 output = internal::union_find_dispatch(f, g, nbh);
283 trace::exiting("morpho::reconstruction::by_dilation::union_find");
287 # endif // ! MLN_INCLUDE_ONLY
298 #endif // ! MLN_MORPHO_RECONSTRUCTION_BY_DILATION_UNION_FIND_HH