27 #ifndef MLN_CANVAS_LABELING_SORTED_HH
28 # define MLN_CANVAS_LABELING_SORTED_HH
35 # include <mln/core/concept/image.hh>
36 # include <mln/data/fill.hh>
37 # include <mln/literal/zero.hh>
38 # include <mln/extension/adjust_fill.hh>
40 # include <mln/data/sort_psites.hh>
41 # include <mln/data/sort_offsets.hh>
43 # include <mln/canvas/labeling/generic.hh>
44 # include <mln/canvas/labeling/internal/tests.hh>
45 # include <mln/canvas/labeling/internal/find_root_fastest.hh>
63 template <
typename I,
typename N,
typename L,
typename F>
66 sorted(const Image<I>& input, const Neighborhood<N>& nbh,
67 L& nlabels, F& functor,
bool increasing);
70 # ifndef MLN_INCLUDE_ONLY
80 template <
typename I,
typename N,
typename L,
81 typename S,
typename F>
83 sorted_fastest(const Image<I>& input_,
84 const Neighborhood<N>& nbh_, L& nlabels,
87 mln_trace(
"canvas::impl::labeling::sorted_fastest");
91 const I& input =
exact(input_);
92 const N& nbh =
exact(nbh_);
97 typedef mln_psite(I) P;
100 mln_ch_value(I,
bool) deja_vu;
101 mln_ch_value(I,
unsigned) parent;
104 mln_ch_value(I, L) output;
121 util::array<int>
dp = offsets_wrt(input, nbh);
122 const unsigned n_nbhs = dp.nelements();
124 const unsigned n_points = s.nelements();
128 for (
int i = n_points - 1; i >=0; --i)
135 parent.element(p) =
p;
138 for (
unsigned j = 0; j < n_nbhs; ++j)
140 unsigned n = p + dp[j];
141 if (! deja_vu.element(n))
150 parent.element(r) =
p;
155 f.do_no_union_(n, p);
157 deja_vu.element(p) =
true;
163 for (
unsigned i = 0; i < n_points; ++i)
169 if (parent.element(p) ==
p)
173 if (nlabels == mln_max(L))
175 mln_trace_warning(
"labeling aborted! Too many labels \
176 for this label type: nlabels > \
180 output.element(p) = ++nlabels;
184 output.element(p) = output.element(parent.element(p));
199 template <
typename I,
typename N,
typename L,
typename F>
202 sorted_dispatch(metal::false_,
203 const Image<I>& input,
204 const Neighborhood<N>& nbh, L& nlabels,
205 F& functor,
bool increasing)
207 p_array<mln_psite(I)> s =
215 template <
typename I,
typename N,
typename L,
typename F>
218 sorted_dispatch(metal::true_,
219 const Image<I>& input,
220 const Neighborhood<N>& nbh, L& nlabels,
221 F& functor,
bool increasing)
223 util::array<unsigned> s =
226 data::sort_offsets_decreasing(input);
227 return impl::sorted_fastest(input, nbh, nlabels, s,
231 template <
typename I,
typename N,
typename L,
typename F>
234 sorted_dispatch(const Image<I>& input,
235 const Neighborhood<N>& nbh, L& nlabels,
236 F& functor,
bool increasing)
239 test = mlc_equal(mln_trait_image_speed(I),
240 trait::image::speed::fastest)::
value
242 mln_is_simple_neighborhood(N)::
value
244 return sorted_dispatch(metal::bool_<test>(),
246 functor, increasing);
257 template <
typename I,
typename N,
typename L,
typename F>
260 sorted(const Image<I>& input, const Neighborhood<N>& nbh,
261 L& nlabels, F& functor,
bool increasing)
263 mln_trace(
"canvas::labeling::sorted");
267 mln_ch_value(I, L) output;
268 output = internal::sorted_dispatch(input, nbh, nlabels,
269 functor, increasing);
275 # endif // ! MLN_INCLUDE_ONLY
284 #endif // ! MLN_CANVAS_LABELING_SORTED_HH