27 #ifndef MLN_CANVAS_LABELING_BLOBS_HH
28 # define MLN_CANVAS_LABELING_BLOBS_HH
35 # include <mln/core/concept/image.hh>
36 # include <mln/core/concept/neighborhood.hh>
37 # include <mln/data/fill.hh>
38 # include <mln/core/site_set/p_queue_fast.hh>
40 # include <mln/extension/fill.hh>
42 # include <mln/util/pix.hh>
69 template <
typename I,
typename N,
typename L,
typename F>
71 blobs(const Image<I>& input_, const Neighborhood<N>& nbh_,
72 L& nlabels, F& functor);
76 # ifndef MLN_INCLUDE_ONLY
89 template <
typename I,
typename N,
typename L,
typename F>
91 blobs(const Image<I>& input_, const N& nbh, L& nlabels, F& functor)
93 const I& input = exact(input_);
95 typedef mln_psite(I) P;
98 mln_niter(N) n(nbh, cur);
100 const L zero = literal::zero;
103 nlabels = literal::zero;
104 typedef mln_ch_value(I, L) out_t;
107 data::fill(output, zero);
109 extension::fill(input, false);
114 mln_piter(I) p(input.domain());
116 if (input(p) && output(p) == zero)
119 if (nlabels == mln_max(L))
121 trace::warning(
"labeling aborted! Too many labels \
122 for this label type: nlabels > max(label_type).");
127 functor.new_label(nlabels);
128 mln_invariant(qu.is_empty());
131 functor.process_p(p);
137 for_all(n) if (input.has(n))
138 if (input(n) && output(n) == zero)
140 mln_invariant(! qu.compute_has(n));
143 functor.process_n(n);
147 while (! qu.is_empty());
164 template <
typename I,
typename N,
typename L,
typename F>
168 L& nlabels, F& functor)
170 trace::entering(
"labeling::blobs");
171 mlc_equal(mln_trait_image_kind(I),
172 mln::trait::image::kind::binary)::check();
173 const I& input = exact(input_);
174 const N& nbh = exact(nbh_);
175 mln_precondition(input.is_valid());
179 output = impl::generic::blobs(input, nbh, nlabels, functor);
181 trace::exiting(
"labeling::blobs");
186 # endif // ! MLN_INCLUDE_ONLY
195 #endif // ! MLN_CANVAS_LABELING_BLOBS_HH