27 #ifndef MLN_MORPHO_RECONSTRUCTION_BY_EROSION_UNION_FIND_HH
28 # define MLN_MORPHO_RECONSTRUCTION_BY_EROSION_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_erosion::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);
132 typedef mln_site(I) P;
133 typedef mln_value(I) V;
137 mln_ch_value(I,
bool) deja_vu;
138 mln_ch_value(I, P) parent;
139 mln_concrete(I) output;
154 for (
unsigned i = 0; i < s.nsites(); ++i)
158 mln_niter(N) n(nbh, p);
166 if (f.domain().has(n) && deja_vu(n))
169 P r = internal::find_root(parent, n);
172 if (g(r) == g(p) || g(p) <= output(r))
175 if (output(r) < output(p))
176 output(p) = output(r);
179 output(p) = mln_min(V);
189 for (
int i = s.nsites() - 1; i >= 0; --i)
194 if (output(p) == mln_min(V))
198 output(p) = output(parent(p));
202 mln_postcondition(output >= f);
203 mln_postcondition(output >= g);
218 template <
typename I,
typename J,
typename N>
221 union_find_dispatch(trait::image::kind::logic,
222 const Image<I>& f, const Image<J>& g,
223 const Neighborhood<N>& nbh)
230 << __FILE__ <<
":" << __LINE__ <<
": error:\n"
231 "mln::morpho::reconstruction::by_erosion::internal::\n"
232 " union_find_dispatch(mln::trait::image::kind::logic,\n"
233 " const mln::Image<I>&,\n"
234 " const mln::Image<J>&,\n"
235 " const mln::Neighborhood<N>&)\n"
241 template <
typename I,
typename J,
typename N>
244 union_find_dispatch(trait::image::kind::any,
245 const Image<I>& f, const Image<J>& g,
246 const Neighborhood<N>& nbh)
251 template <
typename I,
typename J,
typename N>
254 union_find_dispatch(const Image<I>& f, const Image<J>& g,
255 const Neighborhood<N>& nbh)
257 return union_find_dispatch(mln_trait_image_kind(I)(),
266 template <
typename I,
typename J,
typename N>
269 union_find(const Image<I>& f, const Image<J>& g,
270 const Neighborhood<N>& nbh)
272 mln_trace(
"morpho::reconstruction::by_erosion::union_find");
274 internal::union_find_tests(f, g, nbh);
276 mln_concrete(I) output;
277 output = internal::union_find_dispatch(f, g, nbh);
282 # endif // ! MLN_INCLUDE_ONLY
293 #endif // ! MLN_MORPHO_RECONSTRUCTION_BY_EROSION_UNION_FIND_HH