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 trace::entering(
"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;
133 data::fill(is_crest, false);
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)
162 trace::exiting(
"topo::skeleton::impl::generic::crest");
171 template <
typename I,
typename D,
typename N>
173 crest_fastest_2d(const Image<I>& input_, const Image<D>& dist_map_,
174 const Neighborhood<N>& nbh_,
unsigned psi_threshold)
176 trace::entering(
"topo::skeleton::impl::crest_fastest_2d");
178 const I& input = exact(input_);
179 const D& dist_map = exact(dist_map_);
180 const N& nbh = exact(nbh_);
182 mlc_equal(mln_value(I),
bool)::check();
183 mln_precondition(input.is_valid());
184 mln_precondition(dist_map.is_valid());
185 mln_precondition(nbh.is_valid());
186 mln_precondition(input.domain() == dist_map.domain());
191 mln_concrete(I) is_crest;
193 data::fill(is_crest, false);
196 mln_pixter(const I) p(input);
197 util::array<
int> dp = mln::offsets_wrt(input, nbh);
198 unsigned n_nbhs = dp.nelements();
202 || dist_map.element(p) <
static_cast<mln_value(D)
>(0))
207 for (
unsigned i = 0; i < n_nbhs; ++i)
209 unsigned n = p.offset() + dp[i];
214 dist_map.element(n) >
static_cast<mln_value(D)
>(0))
216 if (dist_map.element(n) == dist_map.element(p))
218 else if (dist_map.element(n) < dist_map.element(p))
222 if ((nb_lt + nb_eq) >= psi_threshold)
223 is_crest.element(p) =
true;
228 trace::exiting(
"topo::skeleton::impl::crest_fastest_2d");
240 template <
typename I,
typename D,
typename N>
242 crest_dispatch_2d(mln::trait::image::value_storage::any,
243 mln::trait::image::value_access::any,
244 mln::trait::image::ext_domain::any,
245 const Image<I>& input, const Image<D>& dist_map,
246 const Neighborhood<N>& nbh,
unsigned psi_threshold)
248 return skeleton::impl::generic::crest(input, dist_map,
253 template <
typename I,
typename D,
typename N>
255 crest_dispatch_2d(mln::trait::image::value_storage::one_block,
256 mln::trait::image::value_access::direct,
257 mln::trait::image::ext_domain::some,
258 const Image<I>& input, const Image<D>& dist_map,
259 const Neighborhood<N>& nbh,
unsigned psi_threshold)
261 return skeleton::impl::crest_fastest_2d(input, dist_map,
266 template <
typename I,
typename D,
typename N>
268 crest_dispatch(const Image<I>& input, const Image<D>& dist_map,
269 const Neighborhood<N>& nbh,
unsigned psi_threshold)
271 unsigned dim = mln_site_(I)::dim;
275 crest_dispatch_2d(mln_trait_image_value_storage(I)(),
276 mln_trait_image_value_access(I)(),
277 mln_trait_image_ext_domain(I)(),
278 input, dist_map, nbh, psi_threshold);
280 return impl::generic::crest(input, dist_map, nbh, psi_threshold);
289 template <
typename I,
typename D,
typename N>
291 crest(const Image<I>& input, const Image<D>& dist_map,
292 const Neighborhood<N>& nbh,
unsigned psi_threshold)
294 trace::entering(
"topo::skeleton::crest");
296 mlc_equal(mln_value(I),
bool)::check();
297 mln_precondition(exact(input).is_valid());
298 mln_precondition(exact(dist_map).is_valid());
299 mln_precondition(exact(nbh).is_valid());
302 output = internal::crest_dispatch(input, dist_map,
305 trace::exiting("topo::skeleton::crest");
310 template <typename I, typename D, typename N>
312 crest(const Image<I>& input, const Image<D>& dist_map,
313 const Neighborhood<N>& nbh)
315 return crest(input, dist_map, nbh, 6);
318 # endif // ! MLN_INCLUDE_ONLY
327 #endif // ! MLN_TOPO_SKELETON_CREST_HH