26 #ifndef MLN_MORPHO_ELEMENTARY_GRADIENT_HH
27 # define MLN_MORPHO_ELEMENTARY_GRADIENT_HH
33 # include <mln/morpho/includes.hh>
34 # include <mln/accu/stat/min_max.hh>
47 template <
typename I,
typename N>
49 gradient(const Image<I>& input, const Neighborhood<N>&
nbh);
52 # ifndef MLN_INCLUDE_ONLY
57 template <
typename I,
typename N>
59 gradient_tests(
const Image<I>& input,
const Neighborhood<N>& nbh)
61 mln_precondition(
exact(input).is_valid());
62 mln_precondition(
exact(nbh).is_valid());
73 template <
typename I,
typename N>
75 gradient_on_function(const Image<I>& input_, const Neighborhood<N>& nbh_)
77 mln_trace(
"morpho::elementary::impl::gradient_on_function");
79 const I& input =
exact(input_);
80 const N& nbh =
exact(nbh_);
81 internal::gradient_tests(input, nbh);
83 accu::stat::min_max<mln_value(I)> a;
87 mln_concrete(I) output;
90 mln_piter(I)
p(input.domain());
91 mln_niter(N) n(nbh,
p);
94 a.take_as_init(input(p));
95 for_all(n) if (input.has(n))
97 output(p) = a.second() - a.first();
103 template <typename I, typename N>
105 gradient_on_set(const Image<I>& input_, const Neighborhood<N>& nbh_)
107 mln_trace(
"morpho::elementary::impl::gradient_on_set");
109 const I& input =
exact(input_);
110 const N& nbh =
exact(nbh_);
111 internal::gradient_tests(input, nbh);
115 mln_concrete(I) output;
119 mln_piter(I) p(input.domain());
120 mln_niter(N) n(nbh, p);
122 if (input(p) == true)
124 for_all(n) if (input.has(n))
125 if (input(n) == false)
133 for_all(n) if (input.has(n))
134 if (input(n) == true)
145 template <
typename I,
typename N>
147 gradient_on_function_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_)
149 mln_trace(
"morpho::elementary::impl::gradient_on_function_fastest");
151 const I& input =
exact(input_);
152 const N& nbh =
exact(nbh_);
153 internal::gradient_tests(input, nbh);
155 accu::stat::min_max<mln_value(I)> a;
158 typedef mln_concrete(I) O;
162 mln_pixter(const I) p_in(input);
163 mln_pixter(O) p_out(output);
164 mln_nixter(const I, N) n(p_in, nbh);
165 for_all_2(p_in, p_out)
167 a.take_as_init(p_in.val());
170 p_out.val() = a.second() - a.first();
184 template <
typename I,
typename N>
186 gradient_dispatch(trait::image::kind::any,
187 trait::image::speed::any,
188 const Image<I>& input, const Neighborhood<N>& nbh)
190 return impl::gradient_on_function(input, nbh);
193 template <
typename I,
typename N>
195 gradient_dispatch(trait::image::kind::any,
196 trait::image::speed::fastest,
197 const Image<I>& input, const Neighborhood<N>& nbh)
199 return impl::gradient_on_function_fastest(input, nbh);
202 template <
typename I,
typename N>
204 gradient_dispatch(trait::image::kind::logic,
205 trait::image::speed::any,
206 const Image<I>& input, const Neighborhood<N>& nbh)
208 return impl::gradient_on_set(input, nbh);
213 template <
typename I,
typename N>
215 gradient_dispatch(trait::image::kind::logic,
216 trait::image::speed::fastest,
217 const Image<I>& input, const Neighborhood<N>& nbh)
219 return impl::gradient_on_set(input, nbh);
222 template <
typename I,
typename N>
224 gradient_dispatch(const Image<I>& input, const Neighborhood<N>& nbh)
226 return gradient_dispatch(mln_trait_image_kind(I)(),
227 mln_trait_image_speed(I)(),
236 template <
typename I,
typename N>
238 gradient(const Image<I>& input, const Neighborhood<N>& nbh)
240 mln_trace(
"morpho::elementary::gradient");
242 internal::gradient_tests(input, nbh);
243 mln_concrete(I) output = internal::gradient_dispatch(input, nbh);
248 # endif // ! MLN_INCLUDE_ONLY
257 #endif // ! MLN_MORPHO_ELEMENTARY_GRADIENT_HH