Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
elementary/gradient.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_MORPHO_ELEMENTARY_GRADIENT_HH
27 # define MLN_MORPHO_ELEMENTARY_GRADIENT_HH
28 
32 
33 # include <mln/morpho/includes.hh>
34 # include <mln/accu/stat/min_max.hh>
35 
36 
37 namespace mln
38 {
39 
40  namespace morpho
41  {
42 
43  namespace elementary
44  {
45 
46 
47  template <typename I, typename N>
48  mln_concrete(I)
49  gradient(const Image<I>& input, const Neighborhood<N>& nbh);
50 
51 
52 # ifndef MLN_INCLUDE_ONLY
53 
54  namespace internal
55  {
56 
57  template <typename I, typename N>
58  void
59  gradient_tests(const Image<I>& input, const Neighborhood<N>& nbh)
60  {
61  mln_precondition(exact(input).is_valid());
62  mln_precondition(exact(nbh).is_valid());
63  (void) input;
64  (void) nbh;
65  }
66 
67  } // end of namespace mln::morpho::elementary::tests
68 
69 
70  namespace impl
71  {
72 
73  template <typename I, typename N>
74  mln_concrete(I)
75  gradient_on_function(const Image<I>& input_, const Neighborhood<N>& nbh_)
76  {
77  trace::entering("morpho::elementary::impl::gradient_on_function");
78 
79  const I& input = exact(input_);
80  const N& nbh = exact(nbh_);
81  internal::gradient_tests(input, nbh);
82 
83  accu::stat::min_max<mln_value(I)> a;
84 
85  extension::adjust_duplicate(input, nbh);
86 
87  mln_concrete(I) output;
88  initialize(output, input);
89 
90  mln_piter(I) p(input.domain());
91  mln_niter(N) n(nbh, p);
92  for_all(p)
93  {
94  a.take_as_init(input(p));
95  for_all(n) if (input.has(n))
96  a.take(input(n));
97  output(p) = a.second() - a.first();
98  }
99 
100  trace::exiting("morpho::elementary::impl::gradient_on_function");
101  return output;
102  }
103 
104  template <typename I, typename N>
105  mln_concrete(I)
106  gradient_on_set(const Image<I>& input_, const Neighborhood<N>& nbh_)
107  {
108  trace::entering("morpho::elementary::impl::gradient_on_set");
109 
110  const I& input = exact(input_);
111  const N& nbh = exact(nbh_);
112  internal::gradient_tests(input, nbh);
113 
114  extension::adjust_duplicate(input, nbh);
115 
116  mln_concrete(I) output;
117  initialize(output, input);
118  data::fill(output, false);
119 
120  mln_piter(I) p(input.domain());
121  mln_niter(N) n(nbh, p);
122  for_all(p)
123  if (input(p) == true)
124  {
125  for_all(n) if (input.has(n))
126  if (input(n) == false)
127  {
128  output(p) = true;
129  break;
130  }
131  }
132  else // input(p) == false
133  {
134  for_all(n) if (input.has(n))
135  if (input(n) == true)
136  {
137  output(p) = true;
138  break;
139  }
140  }
141 
142  trace::exiting("morpho::elementary::impl::gradient_on_set");
143  return output;
144  }
145 
146 
147  template <typename I, typename N>
148  mln_concrete(I)
149  gradient_on_function_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_)
150  {
151  trace::entering("morpho::elementary::impl::gradient_on_function_fastest");
152 
153  const I& input = exact(input_);
154  const N& nbh = exact(nbh_);
155  internal::gradient_tests(input, nbh);
156 
157  accu::stat::min_max<mln_value(I)> a;
158  extension::adjust_duplicate(input, nbh);
159 
160  typedef mln_concrete(I) O;
161  O output;
162  initialize(output, input);
163 
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)
168  {
169  a.take_as_init(p_in.val());
170  for_all(n)
171  a.take(n.val());
172  p_out.val() = a.second() - a.first();
173  }
174 
175  trace::exiting("morpho::elementary::impl::gradient_on_function_fastest");
176  return output;
177  }
178 
179  } // end of namespace mln::morpho::elementary::impl
180 
181 
182  namespace internal
183  {
184 
185  // Dispatch.
186 
187  template <typename I, typename N>
188  mln_concrete(I)
189  gradient_dispatch(trait::image::kind::any,
190  trait::image::speed::any,
191  const Image<I>& input, const Neighborhood<N>& nbh)
192  {
193  return impl::gradient_on_function(input, nbh);
194  }
195 
196  template <typename I, typename N>
197  mln_concrete(I)
198  gradient_dispatch(trait::image::kind::any,
199  trait::image::speed::fastest,
200  const Image<I>& input, const Neighborhood<N>& nbh)
201  {
202  return impl::gradient_on_function_fastest(input, nbh);
203  }
204 
205  template <typename I, typename N>
206  mln_concrete(I)
207  gradient_dispatch(trait::image::kind::logic,
208  trait::image::speed::any,
209  const Image<I>& input, const Neighborhood<N>& nbh)
210  {
211  return impl::gradient_on_set(input, nbh);
212  }
213 
214  // May be redundant with the previous version but fixes an ambiguity
215  // with image*d<bool> which is fasted AND logic.
216  template <typename I, typename N>
217  mln_concrete(I)
218  gradient_dispatch(trait::image::kind::logic,
219  trait::image::speed::fastest,
220  const Image<I>& input, const Neighborhood<N>& nbh)
221  {
222  return impl::gradient_on_set(input, nbh);
223  }
224 
225  template <typename I, typename N>
226  mln_concrete(I)
227  gradient_dispatch(const Image<I>& input, const Neighborhood<N>& nbh)
228  {
229  return gradient_dispatch(mln_trait_image_kind(I)(),
230  mln_trait_image_speed(I)(),
231  input, nbh);
232  }
233 
234  } // end of namespace mln::morpho::elementary::internal
235 
236 
237  // Facade.
238 
239  template <typename I, typename N>
240  mln_concrete(I)
241  gradient(const Image<I>& input, const Neighborhood<N>& nbh)
242  {
243  trace::entering("morpho::elementary::gradient");
244 
245  internal::gradient_tests(input, nbh);
246  mln_concrete(I) output = internal::gradient_dispatch(input, nbh);
247 
248  trace::exiting("morpho::elementary::gradient");
249  return output;
250  }
251 
252 # endif // ! MLN_INCLUDE_ONLY
253 
254  } // end of namespace mln::morpho::elementary
255 
256  } // end of namespace mln::morpho
257 
258 } // end of namespace mln
259 
260 
261 #endif // ! MLN_MORPHO_ELEMENTARY_GRADIENT_HH