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 mln_trace(
"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);
220 template <
typename I,
typename J,
typename N>
223 union_find_dispatch(trait::image::kind::logic,
224 const Image<I>& f, const Image<J>& g,
225 const Neighborhood<N>& nbh)
232 << __FILE__ <<
":" << __LINE__ <<
": error:\n"
233 "mln::morpho::reconstruction::by_dilation::internal::\n"
234 " union_find_dispatch(mln::trait::image::kind::logic,\n"
235 " const mln::Image<I>&,\n"
236 " const mln::Image<J>&,\n"
237 " const mln::Neighborhood<N>&)\n"
243 template <
typename I,
typename J,
typename N>
246 union_find_dispatch(trait::image::kind::any,
247 const Image<I>& f, const Image<J>& g,
248 const Neighborhood<N>& nbh)
253 template <
typename I,
typename J,
typename N>
256 union_find_dispatch(const Image<I>& f, const Image<J>& g,
257 const Neighborhood<N>& nbh)
259 return union_find_dispatch(mln_trait_image_kind(I)(),
268 template <
typename I,
typename J,
typename N>
271 union_find(const Image<I>& f, const Image<J>& g,
272 const Neighborhood<N>& nbh)
274 mln_trace(
"morpho::reconstruction::by_dilation::union_find");
276 internal::union_find_tests(f, g, nbh);
278 mln_concrete(I) output;
279 output = internal::union_find_dispatch(f, g, nbh);
284 # endif // ! MLN_INCLUDE_ONLY
295 #endif // ! MLN_MORPHO_RECONSTRUCTION_BY_DILATION_UNION_FIND_HH