27 #ifndef MLN_CANVAS_LABELING_VIDEO_HH
28 # define MLN_CANVAS_LABELING_VIDEO_HH
37 # include <mln/core/concept/image.hh>
38 # include <mln/data/fill.hh>
39 # include <mln/literal/zero.hh>
40 # include <mln/extension/adjust_fill.hh>
42 # include <mln/canvas/labeling/internal/tests.hh>
43 # include <mln/canvas/labeling/internal/find_root_fastest.hh>
44 # include <mln/canvas/labeling/generic.hh>
55 template <
typename I,
typename N,
typename L,
typename F>
57 video(const Image<I>& input, const Neighborhood<N>& nbh,
58 L& nlabels, F& functor);
61 # ifndef MLN_INCLUDE_ONLY
69 template <
typename I,
typename N,
typename L,
typename F>
71 video_fastest(const Image<I>& input_,
72 const Neighborhood<N>& nbh_,
75 trace::entering(
"canvas::impl::video_fastest");
79 const I& input = exact(input_);
80 const N& nbh = exact(nbh_);
85 mln_ch_value(I,
bool) deja_vu;
86 mln_ch_value(I,
unsigned) parent;
89 mln_ch_value(I, L) output;
109 util::array<int> dp = positive_offsets_wrt(input, nbh);
110 const unsigned n_nbhs = dp.nelements();
112 mln_bkd_pixter(
const I) px(input);
115 unsigned p = px.offset();
120 parent.element(p) = p;
122 for (
unsigned i = 0; i < n_nbhs; ++i)
124 unsigned n = p + dp[i];
125 if (deja_vu.element(n))
130 unsigned r = internal::find_root_fastest(parent, n);
133 parent.element(r) = p;
138 f.do_no_union_(n, p);
146 mln_fwd_pixter(
const I) px(input);
149 unsigned p = px.offset();
152 if (parent.element(p) == p)
156 if (nlabels == mln_max(L))
159 trace::warning(
"labeling aborted! Too many labels for \
160 this label type: nlabels > \
164 output.element(p) = ++nlabels;
165 f.set_new_label_(p, nlabels);
170 L lbl = output.element(parent.element(p));
171 output.element(p) = lbl;
172 f.set_label_(p, lbl);
179 trace::exiting(
"canvas::impl::video_fastest");
192 template <
typename I,
typename N,
typename L,
typename F>
195 video_dispatch(metal::false_,
196 const Image<I>& input,
197 const Neighborhood<N>& nbh, L& nlabels,
200 return impl::generic::labeling(input, nbh, nlabels,
201 exact(input).domain(), functor);
204 template <
typename I,
typename N,
typename L,
typename F>
207 video_dispatch(metal::true_,
208 const Image<I>& input,
209 const Neighborhood<N>& nbh, L& nlabels,
212 return impl::video_fastest(input, nbh, nlabels, functor);
215 template <
typename I,
typename N,
typename L,
typename F>
218 video_dispatch(const Image<I>& input,
219 const Neighborhood<N>& nbh, L& nlabels,
223 test = mlc_equal(mln_trait_image_speed(I),
224 trait::image::speed::fastest)::
value
226 mln_is_simple_neighborhood(N)::
value
228 return video_dispatch(metal::bool_<test>(),
241 template <
typename I,
typename N,
typename L,
typename F>
244 video(const Image<I>& input, const Neighborhood<N>& nbh,
245 L& nlabels, F& functor)
247 trace::entering(
"canvas::video");
249 internal::labeling_tests(input, nbh, nlabels, functor);
251 mln_ch_value(I, L) output;
252 output = internal::video_dispatch(input, nbh, nlabels,
255 trace::exiting("canvas::video");
259 # endif // ! MLN_INCLUDE_ONLY
268 #endif // ! MLN_CANVAS_LABELING_VIDEO_HH