$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
dilation-lena.hh
1 // Copyright (C) 2010, 2011 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 APPS_BENCH_DILATION_LENA_HH
27 #define APPS_BENCH_DILATION_LENA_HH
28 
31 
32 #include <mln/core/image/image2d.hh>
33 #include <mln/core/alias/window2d.hh>
34 
35 #include <mln/io/pgm/load.hh>
36 #include <mln/io/pgm/save.hh>
37 
38 #include <mln/value/int_u8.hh>
39 
40 #include <mln/accu/stat/max.hh>
41 
42 #include <mln/util/timer.hh>
43 
44 #include "apps/bench/static_window.hh"
45 #include "apps/bench/static_dpoints_pixter.hh"
46 #include "apps/bench/trait.hh"
47 
48 
49 namespace nongen
50 {
52 
53  image dilation(const image& input)
54  {
55  image output (input.nrows(), input.ncols()); // Initialize an output image.
56  for (unsigned int r = 0; r < input.nrows(); ++r) // Iterate on rows.
57  for (unsigned int c = 0; c < input.ncols(); ++c)
58  { // Iterate on columns.
59  unsigned char sup = input.at_(r, c);
60  if (r != 0 && input.at_(r-1, c) > sup) sup = input.at_(r-1, c);
61  if (r != input.nrows() - 1 && input.at_(r+1, c) > sup) sup = input.at_(r+1, c);
62  if (c != 0 && input.at_(r, c-1) > sup) sup = input.at_(r, c-1);
63  if (c != input.ncols() - 1 && input.at_(r, c+1) > sup) sup = input.at_(r, c+1);
64  output.at_(r, c) = sup;
65  }
66  return output;
67  }
68 }
69 
70 namespace nongen_2ptr
71 {
73 
74  image dilation(const image& input)
75  {
76  typedef mln::value::int_u8 val_t;
77  // Offsets corresponding to a 4-c window on INPUT.
78  ptrdiff_t win_offset[4] = { &input.at_(-1, 0) - &input.at_(0, 0),
79  &input.at_(+1, 0) - &input.at_(0, 0),
80  &input.at_( 0, -1) - &input.at_(0, 0),
81  &input.at_( 0, +1) - &input.at_(0, 0) };
82 
83  image output (input.nrows(), input.ncols()); // Initialize an output image.
84  for (unsigned int r = 0; r < input.nrows(); ++r) // Iterate on rows.
85  {
86  const val_t* pi = &input.at_(r, 0);
87  val_t* po = &output.at_(r, 0);
88  for (; pi < &input.at_(r, 0) + input.ncols(); ++pi, ++po)
89  {
90  unsigned char sup = *pi;
91  // (-1, 0) neighbor.
92  if (r != 0
93  && *(pi + win_offset[0]) > sup)
94  sup = *(pi + win_offset[0]);
95  // (+1, 0) neighbor.
96  if (r != input.nrows() - 1
97  && *(pi + win_offset[1]) > sup)
98  sup = *(pi + win_offset[1]);
99  // (0, -1) neighbor.
100  if (pi != &input.at_(r, 0)
101  && *(pi + win_offset[2]) > sup)
102  sup = *(pi + win_offset[2]);
103  // (0, +1) neighbor.
104  if (pi != &input.at_(r, 0) + input.ncols() - 1
105  && *(pi + win_offset[3]) > sup)
106  sup = *(pi + win_offset[3]);
107  *po = sup;
108  }
109  }
110  return output;
111  }
112 }
113 
114 namespace nongen_1ptr
115 {
117 
118  image dilation(const image& input)
119  {
120  typedef mln::value::int_u8 val_t;
121  // Offsets corresponding to a 4-c window on INPUT.
122  ptrdiff_t win_offset[4] = { &input.at_(-1, 0) - &input.at_(0, 0),
123  &input.at_(+1, 0) - &input.at_(0, 0),
124  &input.at_( 0, -1) - &input.at_(0, 0),
125  &input.at_( 0, +1) - &input.at_(0, 0) };
126 
127  image output;
128  initialize(output, input);
129  // Offset between a the pixel located at the same position in
130  // INPUT and OUTPUT.
131  ptrdiff_t output_offset = &output.at_(0, 0) - &input.at_(0, 0);
132 
133  for (unsigned int r = 0; r < input.nrows(); ++r) // Iterate on rows.
134  {
135  for (const val_t* pi = &input.at_(r, 0);
136  pi < &input.at_(r, 0) + input.ncols();
137  ++pi)
138  {
139  unsigned char sup = *pi;
140  // (-1, 0) neighbor.
141  if (r != 0
142  && *(pi + win_offset[0]) > sup)
143  sup = *(pi + win_offset[0]);
144  // (+1, 0) neighbor.
145  if (r != input.nrows() - 1
146  && *(pi + win_offset[1]) > sup)
147  sup = *(pi + win_offset[1]);
148  // (0, -1) neighbor.
149  if (pi != &input.at_(r, 0)
150  && *(pi + win_offset[2]) > sup)
151  sup = *(pi + win_offset[2]);
152  // (0, +1) neighbor.
153  if (pi != &input.at_(r, 0) + input.ncols() - 1
154  && *(pi + win_offset[3]) > sup)
155  sup = *(pi + win_offset[3]);
156  const_cast<val_t&>(*(pi + output_offset)) = sup;
157  }
158  }
159  return output;
160  }
161 }
162 
163 namespace gen
164 {
165  using namespace mln;
166 
167  template <typename I, typename W>
168  mln_concrete(I) dilation(const I& input, const W& win)
169  {
170  mln_concrete(I) output; initialize(output, input); // Initialize output.
171  mln_piter(I) p(input.domain()); // Iterator on sites of the domain of `input'.
172  mln_qiter(W) q(win, p); // Iterator on the neighbors of `p' w.r.t. `win'.
173  for_all(p)
174  {
175  // FIXME: Cheat: replace the accu::supremum by a maximum.
176  mln::accu::stat::max<mln_value(I)> sup; // Accumulator computing the supremum.
177  for_all(q) if (input.has(q))
178  sup.take(input(q));
179  output(p) = sup.to_result();
180  }
181  return output;
182  }
183 }
184 
185 namespace fast
186 {
187  using namespace mln;
188 
189  template <typename I, typename W>
190  mln_concrete(I) dilation(const I& input, const W& win)
191  {
192  typedef mln_concrete(I) O;
193  O output; initialize(output, input); // Initialize output.
194 
195  mln_pixter(const I) pi(input); // Iterator on the pixels of `input'.
196  mln_pixter(O) po(output); // Iterator on the pixels of `output'.
197 
198  mln_qixter(const I, W) q(pi, win); // Iterator on the neighbors of `p' w.r.t. `win'.
199  for_all_2(pi, po)
200  {
201  // FIXME: Cheat: replace the accu::supremum by a maximum.
202  mln::accu::stat::max<mln_value(I)> sup; // Accumulator computing the supremum.
203  for_all(q)
204  sup.take(q.val());
205  po.val() = sup.to_result();
206  }
207  return output;
208  }
209 }
210 
211 namespace fast_noaccu
212 {
213  using namespace mln;
214 
215  template <typename I, typename W>
216  mln_concrete(I) dilation(const I& input, const W& win)
217  {
218  typedef mln_concrete(I) O;
219  O output; initialize(output, input); // Initialize output.
220 
221  mln_pixter(const I) pi(input); // Iterator on the pixels of `input'.
222  mln_pixter(O) po(output); // Iterator on the pixels of `output'.
223 
224  mln_qixter(const I, W) q(pi, win); // Iterator on the neighbors of `p' w.r.t. `win'.
225  for_all_2(pi, po)
226  {
227  // FIXME: Cheat: replace the accu::supremum by a maximum.
228  mln_value(I) sup = mln_min(mln_value(I));
229  for_all(q)
230  if (q.val() > sup)
231  sup = q.val();
232  po.val() = sup;
233  }
234  return output;
235  }
236 }
237 
238 namespace faster
239 {
240  using namespace mln;
241 
242  template <typename I, typename W>
243  mln_concrete(I) dilation(const I& input, const W& win)
244  {
245  typedef mln_concrete(I) O;
246  O output; initialize(output, input); // Initialize output.
247 
248  mln_pixter(const I) p(input); // Iterator on the pixels of `input'.
249 
250  mln_qixter(const I, W) q(p, win); // Iterator on the neighbors of `p' w.r.t. `win'.
251  for_all(p)
252  {
253  // FIXME: Cheat: replace the accu::supremum by a maximum.
254  mln::accu::stat::max<mln_value(I)> sup; // Accumulator computing the supremum.
255  for_all(q)
256  sup.take(q.val());
257  *(output.buffer() + p.offset()) = sup.to_result();
258  }
259  return output;
260  }
261 }
262 
263 namespace faster_noaccu
264 {
265  using namespace mln;
266 
267  template <typename I, typename W>
268  mln_concrete(I) dilation(const I& input, const W& win)
269  {
270  typedef mln_concrete(I) O;
271  O output; initialize(output, input); // Initialize output.
272 
273  mln_pixter(const I) p(input); // Iterator on the pixels of `input'.
274 
275  mln_qixter(const I, W) q(p, win); // Iterator on the neighbors of `p' w.r.t. `win'.
276  for_all(p)
277  {
278  // FIXME: Cheat: replace the accu::supremum by a maximum.
279  mln_value(I) sup = mln_min(mln_value(I));
280  for_all(q)
281  if (q.val() > sup)
282  sup = q.val();
283  *(output.buffer() + p.offset()) = sup;
284  }
285  return output;
286  }
287 }
288 
289 namespace fast_static
290 {
291  using namespace mln;
292 
293  template <typename I, typename W>
294  mln_concrete(I) dilation(const I& input, const W& win)
295  {
296  // `fast_static' has the same implementation as `fast'.
297  return ::fast::dilation(input, win);
298  }
299 }
300 
301 namespace faster_static
302 {
303  using namespace mln;
304 
305  template <typename I, typename W>
306  mln_concrete(I) dilation(const I& input, const W& win)
307  {
308  // `faster_static' has the same implementation as `faster'.
309  return ::faster::dilation(input, win);
310  }
311 }
312 
313 #endif // ! APPS_BENCH_DILATION_LENA_HH