26 #ifndef MLN_CANVAS_LABELING_SORTED_HH
27 # define MLN_CANVAS_LABELING_SORTED_HH
34 # include <mln/core/concept/image.hh>
35 # include <mln/data/fill.hh>
36 # include <mln/literal/zero.hh>
37 # include <mln/extension/adjust_fill.hh>
39 # include <mln/data/sort_psites.hh>
40 # include <mln/data/sort_offsets.hh>
42 # include <mln/canvas/labeling/generic.hh>
43 # include <mln/canvas/labeling/internal/tests.hh>
44 # include <mln/canvas/labeling/internal/find_root_fastest.hh>
57 template <
typename I,
typename N,
typename L,
typename F>
60 sorted(const Image<I>& input, const Neighborhood<N>& nbh,
61 L& nlabels, F& functor,
bool increasing);
64 # ifndef MLN_INCLUDE_ONLY
74 template <
typename I,
typename N,
typename L,
75 typename S,
typename F>
77 sorted_fastest(const Image<I>& input_,
78 const Neighborhood<N>& nbh_, L& nlabels,
81 trace::entering(
"canvas::impl::labeling::sorted_fastest");
85 const I& input = exact(input_);
86 const N& nbh = exact(nbh_);
91 typedef mln_psite(I) P;
94 mln_ch_value(I,
bool) deja_vu;
95 mln_ch_value(I,
unsigned) parent;
98 mln_ch_value(I, L) output;
116 util::array<int> dp = offsets_wrt(input, nbh);
117 const unsigned n_nbhs = dp.nelements();
119 const unsigned n_points = s.nelements();
123 for (
int i = n_points - 1; i >=0; --i)
130 parent.element(p) = p;
133 for (
unsigned j = 0; j < n_nbhs; ++j)
135 unsigned n = p + dp[j];
136 if (! deja_vu.element(n))
142 unsigned r = internal::find_root_fastest(parent, n);
145 parent.element(r) = p;
150 f.do_no_union_(n, p);
152 deja_vu.element(p) =
true;
158 for (
unsigned i = 0; i < n_points; ++i)
164 if (parent.element(p) == p)
168 if (nlabels == mln_max(L))
171 trace::warning(
"labeling aborted! Too many labels \
172 for this label type: nlabels > \
176 output.element(p) = ++nlabels;
180 output.element(p) = output.element(parent.element(p));
185 trace::exiting(
"canvas::impl::labeling::sorted_fastest");
197 template <
typename I,
typename N,
typename L,
typename F>
200 sorted_dispatch(metal::false_,
201 const Image<I>& input,
202 const Neighborhood<N>& nbh, L& nlabels,
203 F& functor,
bool increasing)
205 p_array<mln_psite(I)> s =
209 return impl::generic::labeling(input, nbh, nlabels, s,
213 template <
typename I,
typename N,
typename L,
typename F>
216 sorted_dispatch(metal::true_,
217 const Image<I>& input,
218 const Neighborhood<N>& nbh, L& nlabels,
219 F& functor,
bool increasing)
221 util::array<unsigned> s =
224 data::sort_offsets_decreasing(input);
225 return impl::sorted_fastest(input, nbh, nlabels, s,
229 template <
typename I,
typename N,
typename L,
typename F>
232 sorted_dispatch(const Image<I>& input,
233 const Neighborhood<N>& nbh, L& nlabels,
234 F& functor,
bool increasing)
237 test = mlc_equal(mln_trait_image_speed(I),
238 trait::image::speed::fastest)::
value
240 mln_is_simple_neighborhood(N)::
value
242 return sorted_dispatch(metal::bool_<test>(),
244 functor, increasing);
255 template <
typename I,
typename N,
typename L,
typename F>
258 sorted(const Image<I>& input, const Neighborhood<N>& nbh,
259 L& nlabels, F& functor,
bool increasing)
261 trace::entering(
"canvas::labeling::sorted");
263 internal::labeling_tests(input, nbh, nlabels, functor);
265 mln_ch_value(I, L) output;
266 output = internal::sorted_dispatch(input, nbh, nlabels,
267 functor, increasing);
269 trace::exiting("canvas::labeling::sorted");
274 # endif // ! MLN_INCLUDE_ONLY
283 #endif // ! MLN_CANVAS_LABELING_SORTED_HH