27 #ifndef MLN_MORPHO_SKELETON_CONSTRAINED_HH
28 # define MLN_MORPHO_SKELETON_CONSTRAINED_HH
37 # include <mln/core/concept/image.hh>
38 # include <mln/core/concept/neighborhood.hh>
39 # include <mln/core/site_set/p_queue_fast.hh>
40 # include <mln/core/site_set/p_priority.hh>
41 # include <mln/extension/adjust_duplicate.hh>
42 # include <mln/extension/adjust_fill.hh>
43 # include <mln/data/fill.hh>
45 # include <mln/util/timer.hh>
58 typename N,
typename F,
59 typename K,
typename R>
62 const Neighborhood<N>& nbh, const F& is_simple,
63 const Image<K>& constraint, const Image<R>& priority);
67 # ifndef MLN_INCLUDE_ONLY
77 typename N,
typename F,
78 typename K,
typename R>
82 const Neighborhood<N>& nbh_, const F& is_simple,
83 const Image<K>& constraint_, const Image<R>& priority_)
85 mln_trace(
"morpho::skeleton_constrained");
87 const I& input =
exact(input_);
88 const N& nbh =
exact(nbh_);
89 const K& constraint =
exact(constraint_);
90 const R& priority =
exact(priority_);
92 mln_precondition(input.is_valid());
93 mln_precondition(nbh.is_valid());
94 mln_precondition(constraint.is_valid());
95 mln_precondition(priority.is_valid());
97 typedef mln_value(I) V;
98 mlc_is(V,
bool)::check();
106 typedef mln_psite(I) P;
107 typedef p_queue_fast<P> Q;
108 p_priority<mln_value(R), Q> q;
110 mln_concrete(I) output;
117 mln_piter(I)
p(input.domain());
119 if (input(
p) == false &&
120 is_simple.check(input,
p))
123 q.push(priority(p), p);
131 mln_niter(N) n(nbh, p);
132 while (! q.is_empty())
138 constraint(n) == false &&
139 is_simple.check(output, n))
142 q.push(priority(n), n);
153 template <
typename I,
154 typename N,
typename F,
155 typename K,
typename R>
157 mln_ch_value(I,
bool)
158 skeleton_constrained_fast(const Image<I>& input_,
159 const Neighborhood<N>& nbh_,
161 const Image<K>& constraint_,
162 const Image<R>& priority_)
164 mln_trace(
"morpho::skeleton_constrained_fast");
166 const I& input =
exact(input_);
167 const N& nbh =
exact(nbh_);
168 const K& constraint =
exact(constraint_);
169 const R& priority =
exact(priority_);
171 mln_precondition(input.is_valid());
172 mln_precondition(nbh.is_valid());
173 mln_precondition(constraint.is_valid());
174 mln_precondition(priority.is_valid());
176 typedef mln_value(I) V;
177 mlc_is(V,
bool)::check();
189 typedef p_queue_fast<
unsigned> Q;
190 p_priority<mln_value(R), Q> q;
192 mln_concrete(I) output;
199 mln_pixter(
const I) p_in(input);
201 if (p_in.val() == false &&
202 is_simple.check__(input, p_in))
205 q.push(priority.element(p_in.offset()), p_in);
211 util::array<int>
dp = offsets_wrt(input, nbh.foreground());
212 const unsigned n_nbhs = dp.nelements();
213 while (! q.is_empty())
215 unsigned p = q.pop_front();
217 for (
unsigned i = 0; i < n_nbhs; ++i)
219 unsigned n = p + dp[i];
221 if (output.element(n) ==
true &&
222 constraint.element(n) ==
false &&
223 is_simple.check__(output, n))
225 output.element(n) =
false;
226 q.push(priority.element(n), n);
242 template <
typename I,
243 typename N,
typename F,
244 typename K,
typename R>
246 mln_ch_value(I,
bool)
247 skeleton_constrained_dispatch(
248 mln::trait::image::value_access::any,
249 mln::trait::image::value_storage::any,
250 const Image<I>& input,
251 const Neighborhood<N>& nbh,
253 const Image<K>& constraint,
254 const Image<R>& priority)
262 template <
typename I,
263 typename N,
typename F,
264 typename K,
typename R>
266 mln_ch_value(I,
bool)
267 skeleton_constrained_dispatch(
268 mln::trait::image::value_access::direct,
269 mln::trait::image::value_storage::one_block,
270 const Image<I>& input,
271 const Neighborhood<N>& nbh,
273 const Image<K>& constraint,
274 const Image<R>& priority)
276 return impl::skeleton_constrained_fast(input, nbh,
286 template <
typename I,
287 typename N,
typename F,
288 typename K,
typename R>
290 mln_ch_value(I,
bool)
292 const Neighborhood<N>& nbh, const F& is_simple,
293 const Image<K>& constraint, const Image<R>& priority)
295 mln_trace(
"morpho::skeleton_constrained");
297 mln_ch_value(I,
bool)
298 output = internal::skeleton_constrained_dispatch(
299 mln_trait_image_value_access(I)(),
300 mln_trait_image_value_storage(I)(),
301 input, nbh, is_simple, constraint, priority);
306 # endif // ! MLN_INCLUDE_ONLY
313 #endif // ! MLN_MORPHO_SKELETON_CONSTRAINED_HH