$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
gradient-spe-lena.cc
1 // Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #include <iostream>
28 
29 #include <mln/core/image/image2d.hh>
30 #include <mln/core/alias/window2d.hh>
31 
32 #include <mln/io/pgm/load.hh>
33 #include <mln/io/pgm/save.hh>
34 
35 #include <mln/value/int_u8.hh>
36 
37 #include <mln/morpho/includes.hh>
38 #include <mln/morpho/general.hh>
39 
40 #include <mln/accu/logic/lor.hh>
41 #include <mln/accu/logic/land.hh>
42 #include <mln/accu/logic/land_basic.hh>
43 #include <mln/accu/logic/lor_basic.hh>
44 #include <mln/accu/stat/max.hh>
45 #include <mln/accu/stat/min.hh>
46 #include <mln/accu/stat/max_h.hh>
47 #include <mln/accu/stat/min_h.hh>
48 
49 #include "apps/bench/minus.hh"
50 #include "apps/bench/and_not.hh"
51 
52 #include <mln/util/timer.hh>
53 
54 #include "apps/data.hh"
55 
56 // With hard-coded/inlined 4-c structuring element.
57 template <typename I>
58 mln_concrete(I)
59 gradient_spe_0(const mln::Image<I>& ima_)
60 {
61  using namespace mln;
62  typedef mln_value(I) V;
63  typedef mln_psite(I) P;
64 
65  const I& ima = exact(ima_);
66 
67  mln_concrete(I) result;
68  initialize(result, ima);
69 
70  mln_piter(I) p(result.domain());
71  for_all(p)
72  {
73  // FIXME: Use one or two accu(s) instead?
74  V sup = ima(p);
75  V inf = ima(p);
76  {
77  P q(p.row() - 1, p.col());
78  if (ima.has(q))
79  {
80  if (ima(q) > sup) sup = ima(q);
81  if (ima(q) < inf) inf = ima(q);
82  }
83  }
84  {
85  P q(p.row(), p.col() - 1);
86  if (ima.has(q))
87  {
88  if (ima(q) > sup) sup = ima(q);
89  if (ima(q) < inf) inf = ima(q);
90  }
91  }
92  {
93  P q(p.row(), p.col() + 1);
94  if (ima.has(q))
95  {
96  if (ima(q) > sup) sup = ima(q);
97  if (ima(q) < inf) inf = ima(q);
98  }
99  }
100  {
101  P q(p.row() + 1, p.col());
102  if (ima.has(q))
103  {
104  if (ima(q) > sup) sup = ima(q);
105  if (ima(q) < inf) inf = ima(q);
106  }
107  }
108  result(p) = sup - inf;
109  }
110  return result;
111 }
112 
113 template <typename I, typename W>
114 mln_concrete(I)
115 gradient_spe_1(const mln::Image<I>& ima_, const mln::Window<W>& win_)
116 {
117  using namespace mln;
118  typedef mln_value(I) V;
119 
120  const I& ima = exact(ima_);
121  const W& win = exact(win_);
122 
123  mln_concrete(I) result;
124  initialize(result, ima);
125 
126  mln_piter(I) p(result.domain());
127  mln_qiter(W) q(win, p);
128  for_all(p)
129  {
130  // FIXME: Use one or two accu(s) instead?
131  V sup = mln_min(V);
132  V inf = mln_max(V);
133  for_all(q)
134  if (ima.has(q))
135  {
136  if (ima(q) > sup)
137  sup = ima(q);
138  if (ima(q) < inf)
139  inf = ima(q);
140  }
141  result(p) = sup - inf;
142  }
143  return result;
144 }
145 
146 template <typename I, typename W>
147 mln_concrete(I)
148 gradient_spe_2(const mln::Image<I>& ima_, const mln::Window<W>& win_)
149 {
150  using namespace mln;
151  typedef mln_value(I) V;
152 
153  const I& ima = exact(ima_);
154  const W& win = exact(win_);
155 
156  typedef mln_concrete(I) O;
157  O result;
158  initialize(result, ima);
159 
160  mln_pixter(const I) pi(ima);
161  mln_pixter(O) po(result);
162  // FIXME: The arguments of a qixter (p, win) are swapped compared to
163  // a qiter (win, p). Make this uniform?
164  mln_qixter(const I, W) q(pi, win);
165  for_all_2(pi, po)
166  {
167  // FIXME: Use one or two accu(s) instead?
168  V sup = mln_min(V);
169  V inf = mln_max(V);
170  for_all(q)
171  {
172  if (q.val() > sup)
173  sup = q.val();
174  if (q.val() < inf)
175  inf = q.val();
176  }
177  po.val() = sup - inf;
178  }
179  return result;
180 }
181 
182 template <typename I, typename W>
183 mln_concrete(I)
184 gradient_spe_3(const mln::Image<I>& ima_, const mln::Window<W>& win_)
185 {
186  using namespace mln;
187  typedef mln_value(I) V;
188 
189  const I& ima = exact(ima_);
190  const W& win = exact(win_);
191 
192  typedef mln_concrete(I) O;
193  O result;
194  initialize(result, ima);
195 
196  mln_pixter(const I) pi(ima);
197  mln_pixter(O) po(result);
198  // FIXME: The arguments of a qixter (p, win) are swapped compared to
199  // a qiter (win, p). Make this uniform?
200  mln_qixter(const I, W) q(pi, win);
201  for_all_2(pi, po)
202  {
203  // FIXME: Use one or two accu(s) instead?
204  V sup = mln_min(V);
205  V inf = mln_max(V);
206  bool global_sup_reached_p = false;
207  bool global_inf_reached_p = false;
208  for_all(q)
209  {
210  if (!global_sup_reached_p && q.val() > sup)
211  {
212  sup = q.val();
213  if (sup == mln_max(V))
214  {
215  // Global sup reached.
216  if (global_inf_reached_p)
217  break;
218  global_sup_reached_p = true;
219  }
220  }
221  if (!global_inf_reached_p && q.val() < inf)
222  {
223  inf = q.val();
224  if (inf == mln_min(V))
225  {
226  // Global inf reached.
227  if (global_sup_reached_p)
228  break;
229  global_inf_reached_p = true;
230  }
231  }
232  }
233  po.val() = sup - inf;
234  }
235  return result;
236 }
237 
238 
239 // FIXME: Unify accumulators and_not and minus?
240 
241 namespace mln
242 {
243  namespace accu
244  {
245  namespace meta
246  {
251 
256  } // End of namespace mln::accu::meta.
257 
258  } // End of namespace mln::accu.
259 
260 
261 namespace morpho
262 {
263 
264  struct gradient_op
265  {
266  template <typename I>
267  mln_morpho_select_accu(I, lor_basic_minus_land_basic, max_minus_min)
268  accu(const Image<I>&) const
269  {
270  mln_morpho_select_accu(I, lor_basic_minus_land_basic, max_minus_min) tmp;
271  return tmp;
272  }
273 
274  template <typename I>
275  mln_morpho_select_accu(I, lor_minus_land, max_h_minus_min_h)
276  accu_incr(const Image<I>&) const
277  {
278  mln_morpho_select_accu(I, lor_minus_land, max_h_minus_min_h) tmp;
279  return tmp;
280  }
281 
282  // FIXME: Which neutral should we choose?
283  template <typename I>
284  mln_value(I) neutral(const Image<I>&) const
285  {
286  return internal::neutral<I>::infimum();
287  }
288  };
289 
290  template <typename I, typename W>
291  inline
292  mln_concrete(I)
293  gradient_spe_4(const Image<I>& input, const Window<W>& win)
294  {
295  mln_trace("morpho::dilation");
296  mln_precondition(exact(input).is_valid());
297  mln_precondition(! exact(win).is_empty());
298 
299  mln_concrete(I) output = general(gradient_op(), input, win);
300 
301  mln_postcondition(test::positive(output));
302  return output;
303  }
304 
305 } // End of namespace mln::morpho.
306 
307 } // End of namespace mln.
308 
309 
310 
311 int main()
312 {
313  using namespace mln;
314  using value::int_u8;
315 
316  border::thickness = 1;
317  image2d<int_u8> lena;
318  io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
319 
320  image2d<int_u8> g;
321  util::timer t;
322 
323  t.start();
324  g = gradient_spe_0(lena);
325  t.stop();
326  std::cout << t.read() << std::endl;
327  io::pgm::save(g, "gradient-spe-lena-out-0.pgm");
328 
329  t.restart();
330  g = gradient_spe_1(lena, win_c4p());
331  t.stop();
332  std::cout << t.read() << std::endl;
333  io::pgm::save(g, "gradient-spe-lena-out-1.pgm");
334 
335  t.restart();
336  g = gradient_spe_2(lena, win_c4p());
337  t.stop();
338  std::cout << t.read() << std::endl;
339  io::pgm::save(g, "gradient-spe-lena-out-2.pgm");
340 
341  t.restart();
342  g = gradient_spe_3(lena, win_c4p());
343  t.stop();
344  std::cout << t.read() << std::endl;
345  io::pgm::save(g, "gradient-spe-lena-out-3.pgm");
346 
347  t.restart();
349  t.stop();
350  std::cout << t.read() << std::endl;
351  io::pgm::save(g, "gradient-spe-lena-out-4.pgm");
352 }