27 #ifndef MLN_MORPHO_WATERSHED_FLOODING_HH
28 # define MLN_MORPHO_WATERSHED_FLOODING_HH
42 # include <mln/trait/ch_value.hh>
44 # include <mln/morpho/includes.hh>
45 # include <mln/literal/zero.hh>
46 # include <mln/labeling/regional_minima.hh>
48 # include <mln/core/site_set/p_queue_fast.hh>
49 # include <mln/core/site_set/p_priority.hh>
51 # include <mln/extension/adjust_fill.hh>
77 template <
typename L,
typename I,
typename N>
79 flooding(const Image<I>& input, const Neighborhood<N>& nbh,
101 template <typename L, typename I, typename N>
103 flooding(const Image<I>& input, const Neighborhood<N>& nbh);
107 # ifndef MLN_INCLUDE_ONLY
118 template <
typename L,
typename I,
typename N>
120 flooding(const Image<I>& input_, const Neighborhood<N>& nbh_,
123 mln_trace(
"morpho::watershed::impl::generic::flooding");
126 const I input =
exact(input_);
127 const N nbh =
exact(nbh_);
132 typedef mln_value(I) V;
133 const V
max = mln_max(V);
137 typedef mln_ch_value(I, L) O;
140 typedef mln_psite(I)
psite;
143 typedef p_queue_fast<psite> Q;
144 p_priority<V, Q> queue;
147 mln_ch_value(I,
bool) in_queue;
154 mln_piter(I)
p(output.domain());
155 mln_niter(N) n(nbh,
p);
157 if (output(p) == unmarked)
159 if (output.domain().has(n) && output(n) != unmarked)
161 queue.push(
max - input(p), p);
169 while (! queue.is_empty())
171 psite p = queue.front();
175 marker adjacent_marker = unmarked;
177 bool single_adjacent_marker_p =
true;
178 mln_niter(N) n(nbh, p);
180 if (output.domain().has(n) && output(n) != unmarked)
182 if (adjacent_marker == unmarked)
184 adjacent_marker = output(n);
185 single_adjacent_marker_p =
true;
188 if (adjacent_marker != output(n))
190 single_adjacent_marker_p =
false;
198 if (single_adjacent_marker_p)
200 output(p) = adjacent_marker;
202 if (output.domain().has(n) && output(n) == unmarked
205 queue.push(
max - input(n), n);
220 template <
typename I,
typename N,
typename L>
222 flooding_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_,
225 mln_trace(
"morpho::watershed::impl::flooding_fastest");
228 const I input =
exact(input_);
229 const N nbh =
exact(nbh_);
234 typedef mln_value(I) V;
235 const V
max = mln_max(V);
240 typedef mln_ch_value(I, L) O;
242 extension::
fill(output, unmarked);
245 typedef p_queue_fast<
unsigned> Q;
246 p_priority<V, Q> queue;
253 mln_ch_value(I,
bool) in_queue;
256 extension::
fill(in_queue, true);
261 mln_pixter(const O) p_out(output);
262 mln_nixter(const O, N) n_out(p_out, nbh);
264 if (p_out.val() == unmarked)
266 if (n_out.val() != unmarked)
268 unsigned po = p_out.offset();
269 queue.push(max - input.element(po), po);
270 in_queue.element(po) =
true;
277 util::array<int>
dp = offsets_wrt(input, nbh);
278 const unsigned n_nbhs = dp.nelements();
279 while (! queue.is_empty())
281 unsigned p = queue.front();
285 marker adjacent_marker = unmarked;
287 bool single_adjacent_marker_p =
true;
288 for (
unsigned i = 0; i < n_nbhs; ++i)
290 unsigned n = p + dp[i];
292 if (output.element(n) != unmarked)
294 if (adjacent_marker == unmarked)
296 adjacent_marker = output.element(n);
297 single_adjacent_marker_p =
true;
300 if (adjacent_marker != output.element(n))
302 single_adjacent_marker_p =
false;
311 if (single_adjacent_marker_p)
313 output.element(p) = adjacent_marker;
314 for (
unsigned i = 0; i < n_nbhs; ++i)
316 unsigned n = p + dp[i];
317 if (output.element(n) == unmarked
319 && ! in_queue.element(n))
321 queue.push(max - input.element(n), n);
322 in_queue.element(n) =
true;
341 template <
typename I,
typename N,
typename L>
344 flooding_dispatch(metal::false_,
345 const Image<I>& input, const Neighborhood<N>& nbh,
352 template <
typename I,
typename N,
typename L>
355 flooding_dispatch(metal::true_,
356 const Image<I>& input, const Neighborhood<N>& nbh,
359 return impl::flooding_fastest(input, nbh, n_basins);
362 template <
typename I,
typename N,
typename L>
365 flooding_dispatch(const Image<I>& input, const Neighborhood<N>& nbh,
369 test = mlc_equal(mln_trait_image_speed(I),
370 trait::image::speed::fastest)::
value
372 mln_is_simple_neighborhood(N)::
value
374 return flooding_dispatch(metal::bool_<test>(),
375 input, nbh, n_basins);
383 template <
typename L,
typename I,
typename N>
386 flooding(const Image<I>& input, const Neighborhood<N>& nbh, L& n_basins)
388 mln_trace(
"morpho::watershed::flooding");
392 mln_ch_value(I, L) output =
393 internal::flooding_dispatch(input, nbh, n_basins);
398 template <typename L, typename I, typename N>
400 flooding(const Image<I>& input, const Neighborhood<N>& nbh)
403 return flooding<L>(input, nbh, nbasins);
406 # endif // ! MLN_INCLUDE_ONLY
415 #endif // ! MLN_MORPHO_WATERSHED_FLOODING_HH