$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
transform_diagonal.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_ACCU_TRANSFORM_DIAGONAL_HH
27 # define MLN_ACCU_TRANSFORM_DIAGONAL_HH
28 
36 
37 
38 #include <mln/core/concept/image.hh>
39 #include <mln/core/concept/meta_accumulator.hh>
40 #include <mln/core/alias/window2d.hh>
41 #include <mln/win/diff.hh>
42 #include <mln/win/shift.hh>
43 #include <mln/geom/delta.hh>
44 #include <mln/extension/adjust.hh>
45 
46 #include <mln/win/diag2d.hh>
47 #include <mln/canvas/browsing/diagonal2d.hh>
48 
49 #include <mln/win/backdiag2d.hh>
50 #include <mln/canvas/browsing/backdiagonal2d.hh>
51 
52 
53 
54 namespace mln
55 {
56 
57  namespace accu
58  {
59 
60 
61  template <typename A, typename I, typename W>
62  mln_ch_value(I, mln_result(A))
63  transform_diagonal(const Accumulator<A>& a,
64  const Image<I>& input, const Window<W>& win);
65 
66 
67  template <typename A, typename I, typename W>
68  mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
69  transform_diagonal(const Meta_Accumulator<A>& a,
70  const Image<I>& input, const Window<W>& win);
71 
72 
73 
74 # ifndef MLN_INCLUDE_ONLY
75 
76  namespace internal
77  {
78 
79 
80  // Tests.
81 
82 
83  template <typename I, typename W>
84  void transform_diagonal_tests(const Image<I>& input_, const Window<W>& win_)
85  {
86  const I& input = exact(input_);
87  const W& win = exact(win_);
88 
89  mln_precondition(input.is_valid());
90  mln_precondition(win.is_valid());
91  mln_precondition(! win.is_empty());
92 
93  (void) input;
94  (void) win;
95  }
96 
97 
98 
99  // Functors.
100 
101 
102  template <typename I_, typename W, typename A>
103  struct diagonal_functor
104  {
105  typedef I_ I;
106  typedef mln_deduce(I, psite, delta) dpsite;
107 
108  const I& input;
109  const W& win;
110  mln_ch_value(I, mln_result(A)) output;
111  A accu;
112 
113  mln_psite(I) p;
114  typedef mln_site(I) S; // Help g++-2.95.
115  enum { dim = S::dim };
116 
117  window2d win_left, win_right;
118 
119  mln_qiter(window2d) q_l, q_r;
120 
121  diagonal_functor(const I& input, const W& win, const A& a)
122  : input(input),
123  win(win),
124  accu(a),
125  win_left(win::shift(win, dpsite(1, -1)) - win),
126  win_right(win - win::shift(win, dpsite(1, -1))),
127  q_l(win_left, p),
128  q_r(win_right, p)
129  {
130  }
131 
132  void init()
133  {
134  initialize(output, input);
135  }
136 
137  void next()
138  {
139  for_all(q_l)
140  accu.untake(input(q_l));
141  for_all(q_r)
142  accu.take(input(q_r));
143  output(p) = accu;
144  }
145 
146 
147  void init_diag()
148  {
149  accu.init();
150  p = p - dpsite(-1, 1);
151  mln_qiter(W) q(win, p);
152  for_all(q)
153  accu.take(input(q));
154  p = p + dpsite(-1, 1);
155  }
156 
157  void final()
158  {
159  }
160 
161  };
162 
163 
164 
165  template <typename I_, typename W, typename A>
166  struct backdiagonal_functor
167  {
168  typedef I_ I;
169  typedef mln_deduce(I, psite, delta) dpsite;
170 
171  const I& input;
172  const W& win;
173  mln_ch_value(I, mln_result(A)) output;
174  A accu;
175 
176  mln_psite(I) p;
177  typedef mln_site(I) S;
178  enum { dim = S::dim };
179 
180  window2d win_left, win_right;
181 
182  mln_qiter(window2d) q_l, q_r;
183 
184  backdiagonal_functor(const I& input, const W& win, const A& a)
185  : input(input),
186  win(win),
187  accu(a),
188  win_left(win::shift(win, dpsite(-1, -1)) - win),
189  win_right(win - win::shift(win, dpsite(-1, -1))),
190  q_l(win_left, p),
191  q_r(win_right, p)
192  {
193  }
194 
195  void init()
196  {
197  initialize(output, input);
198  }
199 
200  void next()
201  {
202  for_all(q_l)
203  accu.untake(input(q_l));
204  for_all(q_r)
205  accu.take(input(q_r));
206  output(p) = accu;
207  }
208 
209 
210  void init_diag()
211  {
212  accu.init();
213  p = p - dpsite(1, 1);
214  mln_qiter(W) q(win, p);
215  for_all(q)
216  accu.take(input(q));
217  p = p + dpsite(1, 1);
218  }
219 
220  void final()
221  {
222  }
223 
224  };
225 
226 
227 
228  // Functors (fastest versions).
229 
230 
231  template <typename I_, typename W, typename A>
232  struct diagonal_fastest_functor
233  {
234  typedef I_ I;
235  typedef mln_deduce(I, psite, delta) dpsite;
236 
237  const I& input;
238  const W& win;
239  mln_ch_value(I, mln_result(A)) output;
240  A accu;
241 
242  mln_psite(I) p;
243  typedef mln_site(I) S;
244  enum { dim = S::dim };
245 
246  window2d win_left, win_right;
247 
248  mln_qixter(const I, window2d) q_l, q_r;
249 
250  diagonal_fastest_functor(const I& input, const W& win, const A& a)
251  : input(input),
252  win(win),
253  accu(a),
254  win_left(win::shift(win, dpsite(1, -1)) - win),
255  win_right(win - win::shift(win, dpsite(1, -1))),
256  q_l(input, win_left, p),
257  q_r(input, win_right, p)
258  {
259  }
260 
261  void init()
262  {
263  initialize(output, input);
264  }
265 
266  void next()
267  {
268  for_all(q_l)
269  accu.untake(q_l.val());
270  for_all(q_r)
271  accu.take(q_r.val());
272  output(p) = accu;
273  }
274 
275 
276  void init_diag()
277  {
278  accu.init();
279  p = p - dpsite(-1, 1);
280  mln_qixter(const I, W) q(input, win, p);
281  for_all(q)
282  accu.take(q.val());
283  p = p + dpsite(-1, 1);
284  }
285 
286  void final()
287  {
288  }
289 
290  };
291 
292 
293  template <typename I_, typename W, typename A>
294  struct backdiagonal_fastest_functor
295  {
296  typedef I_ I;
297  typedef mln_deduce(I, psite, delta) dpsite;
298 
299  const I& input;
300  const W& win;
301  mln_ch_value(I, mln_result(A)) output;
302  A accu;
303 
304  mln_psite(I) p;
305  typedef mln_site(I) S;
306  enum { dim = S::dim };
307 
308  window2d win_left, win_right;
309 
310  mln_qixter(const I, window2d) q_l, q_r;
311 
312  backdiagonal_fastest_functor(const I& input, const W& win, const A& a)
313  : input(input),
314  win(win),
315  accu(a),
316  win_left(win::shift(win, dpsite(-1, -1)) - win),
317  win_right(win - win::shift(win, dpsite(-1, -1))),
318  q_l(input, win_left, p),
319  q_r(input, win_right, p)
320  {
321  }
322 
323  void init()
324  {
325  initialize(output, input);
326  }
327 
328  void next()
329  {
330  for_all(q_l)
331  accu.untake(q_l.val());
332  for_all(q_r)
333  accu.take(q_r.val());
334  output(p) = accu;
335  }
336 
337 
338  void init_diag()
339  {
340  accu.init();
341  p = p - dpsite(1, 1);
342  mln_qixter(const I, W) q(input, win, p);
343  for_all(q)
344  accu.take(q.val());
345  p = p + dpsite(1, 1);
346  }
347 
348  void final()
349  {
350  }
351 
352  };
353 
354 
355 
356 
357  // Both dispatch and implementation (hum...)
358 
359  template <typename A, typename I>
360  inline
361  mln_ch_value(I, mln_result(A))
362  transform_diagonal_dispatch(metal::false_,
363  const Accumulator<A>& a,
364  const Image<I>& input, const win::diag2d& win)
365  {
366  typedef diagonal_functor<I, win::diag2d, A> F;
367  F f(exact(input), win, exact(a));
369  return f.output;
370  }
371 
372  template <typename B, typename A, typename I>
373  inline
374  mln_ch_value(I, mln_result(A))
375  transform_diagonal_dispatch(metal::false_,
376  const Accumulator<A>& a,
377  const Image<I>& input, const win::backdiag2d& win)
378  {
379  typedef backdiagonal_functor<I, win::backdiag2d, A> F;
380  F f(exact(input), win, exact(a));
382  return f.output;
383  }
384 
385  template <typename A, typename I>
386  inline
387  mln_ch_value(I, mln_result(A))
388  transform_diagonal_dispatch(metal::true_,
389  const Accumulator<A>& a,
390  const Image<I>& input, const win::diag2d& win)
391  {
392  typedef diagonal_fastest_functor<I, win::diag2d, A> F;
393  F f(exact(input), win, exact(a));
395  return f.output;
396  }
397 
398  template <typename A, typename I>
399  inline
400  mln_ch_value(I, mln_result(A))
401  transform_diagonal_dispatch(metal::true_,
402  const Accumulator<A>& a,
403  const Image<I>& input, const win::backdiag2d& win)
404  {
405  typedef backdiagonal_fastest_functor<I, win::backdiag2d, A> F;
406  F f(exact(input), win, exact(a));
408  return f.output;
409  }
410 
411  template <typename A, typename I, typename W>
412  inline
413  mln_ch_value(I, mln_result(A))
414  transform_diagonal_dispatch(const Accumulator<A>& a,
415  const Image<I>& input, const Window<W>& win)
416  {
417  return transform_diagonal_dispatch(mln_is_fastest_IW(I, W)(),
418  a, input, exact(win));
419  }
420 
421  } // end of namespace mln::accu::internal
422 
423 
424 
425 
426  template <typename A, typename I, typename W>
427  inline
428  mln_ch_value(I, mln_result(A))
429  transform_diagonal(const Accumulator<A>& a,
430  const Image<I>& input, const Window<W>& win)
431  {
432  mln_trace("accu::transform_diagonal");
433 
434  internal::transform_diagonal_tests(input, win);
435 
436  extension::adjust(input, geom::delta(win) + 1);
437  mln_ch_value(I, mln_result(A)) output;
438  output = internal::transform_diagonal_dispatch(a, input, win);
439 
440  return output;
441  }
442 
443 
444  template <typename A, typename I, typename W>
445  inline
446  mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
447  transform_diagonal(const Meta_Accumulator<A>& a,
448  const Image<I>& input, const Window<W>& win)
449  {
450  mln_trace("accu::transform_diagonal");
451 
452  internal::transform_diagonal_tests(input, win);
453 
454  typedef mln_accu_with(A, mln_value(I)) A_;
455  A_ a_ = accu::unmeta(exact(a), mln_value(I)());
456 
457  extension::adjust(input, geom::delta(win) + 1);
458  mln_ch_value(I, mln_result(A_)) output;
459  output = internal::transform_diagonal_dispatch(a_, input, win);
460 
461  return output;
462  }
463 
464 
465 # endif // ! MLN_INCLUDE_ONLY
466 
467  } // end of namespace mln::accu
468 
469 } // end of namespace mln
470 
471 
472 #endif // ! MLN_ACCU_TRANSFORM_DIAGONAL_HH