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 trace::entering(
"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;
88 initialize(output, input);
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();
100 trace::exiting("morpho::elementary::impl::gradient_on_function");
104 template <typename I, typename N>
106 gradient_on_set(const Image<I>& input_, const Neighborhood<N>& nbh_)
108 trace::entering(
"morpho::elementary::impl::gradient_on_set");
110 const I& input = exact(input_);
111 const N& nbh = exact(nbh_);
112 internal::gradient_tests(input, nbh);
116 mln_concrete(I) output;
117 initialize(output, input);
118 data::fill(output, false);
120 mln_piter(I) p(input.domain());
121 mln_niter(N) n(nbh, p);
123 if (input(p) == true)
125 for_all(n) if (input.has(n))
126 if (input(n) == false)
134 for_all(n) if (input.has(n))
135 if (input(n) == true)
142 trace::exiting(
"morpho::elementary::impl::gradient_on_set");
147 template <
typename I,
typename N>
149 gradient_on_function_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_)
151 trace::entering(
"morpho::elementary::impl::gradient_on_function_fastest");
153 const I& input = exact(input_);
154 const N& nbh = exact(nbh_);
155 internal::gradient_tests(input, nbh);
157 accu::stat::min_max<mln_value(I)> a;
160 typedef mln_concrete(I) O;
162 initialize(output, input);
164 mln_pixter(const I) p_in(input);
165 mln_pixter(O) p_out(output);
166 mln_nixter(const I, N) n(p_in, nbh);
167 for_all_2(p_in, p_out)
169 a.take_as_init(p_in.val());
172 p_out.val() = a.second() - a.first();
175 trace::exiting("morpho::elementary::impl::gradient_on_function_fastest");
187 template <
typename I,
typename N>
189 gradient_dispatch(trait::image::kind::any,
190 trait::image::speed::any,
191 const Image<I>& input, const Neighborhood<N>& nbh)
193 return impl::gradient_on_function(input, nbh);
196 template <
typename I,
typename N>
198 gradient_dispatch(trait::image::kind::any,
199 trait::image::speed::fastest,
200 const Image<I>& input, const Neighborhood<N>& nbh)
202 return impl::gradient_on_function_fastest(input, nbh);
205 template <
typename I,
typename N>
207 gradient_dispatch(trait::image::kind::logic,
208 trait::image::speed::any,
209 const Image<I>& input, const Neighborhood<N>& nbh)
211 return impl::gradient_on_set(input, nbh);
216 template <
typename I,
typename N>
218 gradient_dispatch(trait::image::kind::logic,
219 trait::image::speed::fastest,
220 const Image<I>& input, const Neighborhood<N>& nbh)
222 return impl::gradient_on_set(input, nbh);
225 template <
typename I,
typename N>
227 gradient_dispatch(const Image<I>& input, const Neighborhood<N>& nbh)
229 return gradient_dispatch(mln_trait_image_kind(I)(),
230 mln_trait_image_speed(I)(),
239 template <
typename I,
typename N>
241 gradient(const Image<I>& input, const Neighborhood<N>& nbh)
243 trace::entering(
"morpho::elementary::gradient");
245 internal::gradient_tests(input, nbh);
246 mln_concrete(I) output = internal::gradient_dispatch(input, nbh);
248 trace::exiting("morpho::elementary::gradient");
252 # endif // ! MLN_INCLUDE_ONLY
261 #endif // ! MLN_MORPHO_ELEMENTARY_GRADIENT_HH