27 #ifndef MLN_TOPO_SKELETON_CREST_HH
28 # define MLN_TOPO_SKELETON_CREST_HH
34 # include <mln/core/concept/image.hh>
35 # include <mln/core/concept/neighborhood.hh>
36 # include <mln/data/fill.hh>
37 # include <mln/extension/adjust.hh>
38 # include <mln/border/equalize.hh>
92 template <
typename I,
typename D,
typename N>
94 crest(const Image<I>& input, const Image<D>& dist_map,
95 const Neighborhood<N>& nbh,
unsigned psi_threshold);
99 template <typename I, typename D, typename N>
101 crest(const Image<I>& input, const Image<D>& dist_map,
102 const Neighborhood<N>& nbh);
106 # ifndef MLN_INCLUDE_ONLY
116 template <
typename I,
typename D,
typename N>
118 crest(const Image<I>& input_, const Image<D>& dist_map_,
119 const Neighborhood<N>& nbh_,
unsigned psi_threshold)
121 mln_trace(
"topo::skeleton::impl::generic::crest");
122 const I& input =
exact(input_);
123 const D& dist_map =
exact(dist_map_);
124 const N& nbh =
exact(nbh_);
126 mlc_equal(mln_value(I),
bool)::check();
127 mln_precondition(input.is_valid());
128 mln_precondition(dist_map.is_valid());
129 mln_precondition(nbh.is_valid());
131 mln_concrete(I) is_crest;
135 mln_piter(I)
p(input.domain());
136 mln_niter(N) n(nbh,
p);
139 if (!input(p) || dist_map(p) <
static_cast<mln_value(D)
>(0))
145 if (input.domain().has(n)
150 && dist_map(n) > static_cast<mln_value(D)>(0))
152 if (dist_map(n) == dist_map(p))
154 else if (dist_map(n) < dist_map(p))
158 if ((nb_lt + nb_eq) >= psi_threshold)
170 template <
typename I,
typename D,
typename N>
172 crest_fastest_2d(const Image<I>& input_, const Image<D>& dist_map_,
173 const Neighborhood<N>& nbh_,
unsigned psi_threshold)
175 mln_trace(
"topo::skeleton::impl::crest_fastest_2d");
177 const I& input =
exact(input_);
178 const D& dist_map =
exact(dist_map_);
179 const N& nbh =
exact(nbh_);
181 mlc_equal(mln_value(I),
bool)::check();
182 mln_precondition(input.is_valid());
183 mln_precondition(dist_map.is_valid());
184 mln_precondition(nbh.is_valid());
185 mln_precondition(input.domain() == dist_map.domain());
190 mln_concrete(I) is_crest;
195 mln_pixter(const I) p(input);
196 util::array<
int> dp = mln::offsets_wrt(input, nbh);
197 unsigned n_nbhs = dp.nelements();
201 || dist_map.element(p) <
static_cast<mln_value(D)
>(0))
206 for (
unsigned i = 0; i < n_nbhs; ++i)
208 unsigned n = p.offset() +
dp[i];
213 dist_map.element(n) >
static_cast<mln_value(D)
>(0))
215 if (dist_map.element(n) == dist_map.element(p))
217 else if (dist_map.element(n) < dist_map.element(p))
221 if ((nb_lt + nb_eq) >= psi_threshold)
222 is_crest.element(p) =
true;
238 template <
typename I,
typename D,
typename N>
240 crest_dispatch_2d(mln::trait::image::value_storage::any,
241 mln::trait::image::value_access::any,
242 mln::trait::image::ext_domain::any,
243 const Image<I>& input, const Image<D>& dist_map,
244 const Neighborhood<N>& nbh,
unsigned psi_threshold)
251 template <
typename I,
typename D,
typename N>
253 crest_dispatch_2d(mln::trait::image::value_storage::one_block,
254 mln::trait::image::value_access::direct,
255 mln::trait::image::ext_domain::some,
256 const Image<I>& input, const Image<D>& dist_map,
257 const Neighborhood<N>& nbh,
unsigned psi_threshold)
259 return skeleton::impl::crest_fastest_2d(input, dist_map,
264 template <
typename I,
typename D,
typename N>
266 crest_dispatch(const Image<I>& input, const Image<D>& dist_map,
267 const Neighborhood<N>& nbh,
unsigned psi_threshold)
269 unsigned dim = mln_site_(I)::dim;
273 crest_dispatch_2d(mln_trait_image_value_storage(I)(),
274 mln_trait_image_value_access(I)(),
275 mln_trait_image_ext_domain(I)(),
276 input, dist_map, nbh, psi_threshold);
287 template <
typename I,
typename D,
typename N>
289 crest(const Image<I>& input, const Image<D>& dist_map,
290 const Neighborhood<N>& nbh,
unsigned psi_threshold)
292 mln_trace(
"topo::skeleton::crest");
294 mlc_equal(mln_value(I),
bool)::check();
295 mln_precondition(
exact(input).is_valid());
296 mln_precondition(
exact(dist_map).is_valid());
297 mln_precondition(
exact(nbh).is_valid());
300 output = internal::crest_dispatch(input, dist_map,
307 template <typename I, typename D, typename N>
309 crest(const Image<I>& input, const Image<D>& dist_map,
310 const Neighborhood<N>& nbh)
312 return crest(input, dist_map, nbh, 6);
315 # endif // ! MLN_INCLUDE_ONLY
324 #endif // ! MLN_TOPO_SKELETON_CREST_HH