$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
transform_line.hh
1 // Copyright (C) 2008, 2009, 2012 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 #ifndef MLN_ACCU_TRANSFORM_LINE_HH
28 # define MLN_ACCU_TRANSFORM_LINE_HH
29 
42 
43 # include <mln/core/concept/image.hh>
44 # include <mln/core/concept/meta_accumulator.hh>
45 # include <mln/extension/adjust.hh>
46 
47 
48 namespace mln
49 {
50 
51  namespace accu
52  {
53 
54 
55  template <typename A, typename I>
56  mln_ch_value(I, mln_result(A))
57  transform_line(const Accumulator<A>& a,
58  const Image<I>& input,
59  unsigned length, unsigned dir);
60 
61  template <typename A, typename I>
62  mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
63  transform_line(const Meta_Accumulator<A>& a,
64  const Image<I>& input,
65  unsigned length, unsigned dir);
66 
67 
68 
69 # ifndef MLN_INCLUDE_ONLY
70 
71 
72  // Tests.
73 
74 
75  namespace internal
76  {
77 
78  template <typename A, typename I>
79  void
80  transform_line_tests(const Accumulator<A>& a_, const Image<I>& input_)
81  {
82  A a = exact(a_);
83  const I& input = exact(input_);
84 
85  mln_precondition(input.is_valid());
86  mln_psite(I)* p;
87  mln_precondition(sizeof(a.take(input(*p)), 0) == sizeof(int));
88 
89  (void) p;
90  (void) a;
91  (void) input;
92  }
93 
94  } // end of namespace mln::accu::internal
95 
96 
97 
98  // Implementations.
99 
100 
101  namespace impl
102  {
103 
104  namespace generic
105  {
106 
107  template <typename A, typename I>
108  inline
109  mln_ch_value(I, mln_result(A))
110  transform_line(const Accumulator<A>& a_,
111  const Image<I>& input_,
112  unsigned length, unsigned dir)
113  {
114  mln_trace("accu::impl::transform_line");
115 
116  const I& input = exact(input_);
117  A a = exact(a_);
118 
119  internal::transform_line_tests(a, input);
120 
121  extension::adjust(input, length / 2); // Safety.
122 
123  mln_ch_value(I, mln_result(A)) output;
124  initialize(output, input);
125 
126  typedef mln_psite(I) P;
127  const P
128  pmin = input.domain().pmin(),
129  pmax = input.domain().pmax();
130  const def::coord
131  pmax_dir = pmax[dir],
132  pmin_dir = pmin[dir];
133 
134  P p = pmin, // Starting point.
135  qt, qu;
136  def::coord& p_dir = p [dir];
137  def::coord& qt_dir = qt[dir];
138  def::coord& qu_dir = qu[dir];
139 
140  do
141  {
142 
143  // Start the line.
144  // ---------------
145 
146  qt = p;
147  qt_dir = p_dir - length / 2;
148  qu = qt;
149  a.init();
150 
151  for (unsigned i = 0; i < length; ++i)
152  {
153  if (input.has(qt))
154  a.take(input(qt));
155  qt_dir++;
156  }
157  if (input.has(p))
158  output(p) = a.to_result();
159 
160  // Browse the line.
161  // ----------------
162 
163  while (p_dir < pmax_dir)
164  {
165  if (input.has(qt))
166  a.take(input(qt));
167  qt_dir++;
168 
169  if (input.has(qu))
170  a.untake(input(qu));
171  qu_dir++;
172 
173  ++p_dir;
174  if (input.has(p))
175  output(p) = a.to_result();
176  }
177 
178  // Go to the next line.
179  // --------------------
180 
181  p_dir = pmin_dir;
182 
183  for (int c = P::dim - 1; c >= 0; --c)
184  {
185  if (c == int(dir))
186  continue;
187  if (p[c] != pmax[c])
188  {
189  ++p[c];
190  break;
191  }
192  p[c] = pmin[c];
193  }
194 
195  } while (p != pmin);
196 
197  return output;
198  }
199 
200  } // end of namespace mln::accu::impl::generic
201 
202 
203  template <typename A, typename I>
204  inline
205  mln_ch_value(I, mln_result(A))
206  transform_line_fastest(const Accumulator<A>& a_,
207  const Image<I>& input_,
208  unsigned length, unsigned dir)
209  {
210  mln_trace("accu::impl::transform_line_fastest");
211 
212  const I& input = exact(input_);
213  A a = exact(a_);
214 
215  internal::transform_line_tests(a, input);
216 
217  extension::adjust(input, length / 2); // Safety.
218 
219  mln_ch_value(I, mln_result(A)) output;
220  initialize(output, input);
221 
222  typedef mln_psite(I) P;
223  const P
224  pmin = input.domain().pmin(),
225  pmax = input.domain().pmax();
226  const def::coord
227  pmax_dir = pmax[dir],
228  pmin_dir = pmin[dir];
229 
230  P p = pmin; // Starting point.
231  def::coord& p_dir = p[dir];
232 
233  // Step.
234  mln_delta(P) dp(literal::zero);
235  dp[dir] = 1;
236  int step = input.delta_offset(dp);
237 
238  do
239  {
240  // Start the line.
241  // ---------------
242 
243  unsigned o_p = input.offset_of_point(p);
244  unsigned o_qt = o_p - (length / 2) * step;
245  unsigned o_qu = o_qt;
246  a.init();
247 
248  for (unsigned i = 0; i < length; ++i)
249  // t o | x o o
250  // ...
251  // o o | x o t
252  {
253  a.take(input.element(o_qt));
254  o_qt += step;
255  }
256  output.element(o_p) = a.to_result();
257 
258  // Browse the line.
259  // ----------------
260 
261  while (p_dir < pmax_dir)
262  // u o | o x o t
263  // ...
264  // u o o x | o t
265  {
266  a.take(input.element(o_qt));
267  o_qt += step;
268 
269  a.untake(input.element(o_qu));
270  o_qu += step;
271 
272  ++p_dir;
273  o_p += step;
274  output.element(o_p) = a.to_result();
275  }
276 
277  // Go to the next line.
278  // --------------------
279 
280  p_dir = pmin_dir;
281 
282  for (int c = P::dim - 1; c >= 0; --c)
283  {
284  if (c == int(dir))
285  continue;
286  if (p[c] != pmax[c])
287  {
288  ++p[c];
289  break;
290  }
291  p[c] = pmin[c];
292  }
293 
294  } while (p != pmin);
295 
296  return output;
297  }
298 
299  /*
300 
301  template <typename A, typename I>
302  inline
303  mln_ch_value(I, mln_result(A))
304  transform_line_fastest_without_border(const Accumulator<A>& a_,
305  const Image<I>& input_,
306  unsigned length, unsigned dir)
307  {
308  mln_trace("accu::impl::transform_line_fastest_without_border");
309 
310  const I& input = exact(input_);
311  A a = exact(a_);
312 
313  internal::transform_line_tests(a, input);
314 
315  mln_ch_value(I, mln_result(A)) output;
316  initialize(output, input);
317 
318  typedef mln_psite(I) P;
319  const P
320  pmin = input.domain().pmin(),
321  pmax = input.domain().pmax();
322  const def::coord
323  pmax_dir = pmax[dir] - length / 2,
324  pmin_dir = pmin[dir];
325 
326  P p = pmin; // Starting point.
327  def::coord& p_dir = p [dir];
328 
329  // Step.
330  mln_delta(P) dp(literal::zero);
331  dp[dir] = 1;
332  int step = input.delta_offset(dp);
333 
334  do
335  {
336  // Start the line.
337  // ---------------
338 
339  unsigned o_p = input.offset_of_point(p);
340  unsigned o_qt = o_p;
341  unsigned o_qu = o_p;
342 
343  a.init();
344 
345  // Causal part.
346  for (unsigned i = 0; i <= length / 2; ++i)
347  // | t
348  // | x t
349  // | x o t
350  {
351  a.take(input.element(o_qt));
352  o_qt += step;
353  }
354  output.element(o_p) = a.to_result();
355 
356  // Non-causal part.
357  for (unsigned i = 0; i < length / 2; ++i)
358  // | x o o <- end of previous loop
359  // | o x o t
360  // | o o x o t
361  {
362  a.take(input.element(o_qt));
363  o_qt += step;
364 
365  ++p_dir;
366  o_p += step;
367  output.element(o_p) = a.to_result();
368  }
369 
370  // Browse the line.
371  // ----------------
372 
373  while (p_dir < pmax_dir)
374  // from .. o o x o o ..
375  // to .. u o o x o t ..
376  {
377  a.take(input.element(o_qt));
378  o_qt += step;
379 
380  a.untake(input.element(o_qu));
381  o_qu += step;
382 
383  ++p_dir;
384  o_p += step;
385  output.element(o_p) = a.to_result();
386  }
387 
388  // Finalize.
389  // ---------
390 
391  for (unsigned i = 0; i < length / 2; ++i)
392  // o o x o o | <- end of previous loop
393  // u o o x o |
394  // u o o x |
395  {
396  a.untake(input.element(o_qu));
397  o_qu += step;
398 
399  o_p += step;
400  output.element(o_p) = a.to_result();
401  }
402 
403  // Go to the next line.
404  // --------------------
405 
406  p_dir = pmin_dir;
407 
408  for (int c = P::dim - 1; c >= 0; --c)
409  {
410  if (c == int(dir))
411  continue;
412  if (p[c] != pmax[c])
413  {
414  ++p[c];
415  break;
416  }
417  p[c] = pmin[c];
418  }
419 
420  } while (p != pmin);
421 
422  return output;
423  }
424 
425  */
426 
427  } // end of namespace mln::accu::impl
428 
429 
430 
431 
432  // Dispatch.
433 
434 
435  namespace internal
436  {
437 
438  template <typename A, typename I>
439  inline
440  mln_ch_value(I, mln_result(A))
441  transform_line_dispatch(trait::image::speed::any,
442  trait::accumulator::when_pix::any,
443  const Accumulator<A>& a,
444  const Image<I>& input,
445  unsigned length, unsigned dir)
446  {
448  input,
449  length, dir);
450  }
451 
452  template <typename A, typename I>
453  inline
454  mln_ch_value(I, mln_result(A))
455  transform_line_dispatch(trait::image::speed::fastest,
456  trait::accumulator::when_pix::use_none,
457  const Accumulator<A>& a,
458  const Image<I>& input,
459  unsigned length, unsigned dir)
460  {
461  return impl::transform_line_fastest(a,
462  input,
463  length, dir);
464  }
465 
466  template <typename A, typename I>
467  inline
468  mln_ch_value(I, mln_result(A))
469  transform_line_dispatch(trait::image::speed::fastest,
470  trait::accumulator::when_pix::use_v,
471  const Accumulator<A>& a,
472  const Image<I>& input,
473  unsigned length, unsigned dir)
474  {
475  return impl::transform_line_fastest(a,
476  input,
477  length, dir);
478  }
479 
480  template <typename A, typename I>
481  inline
482  mln_ch_value(I, mln_result(A))
483  transform_line_dispatch(const Accumulator<A>& a,
484  const Image<I>& input,
485  unsigned length, unsigned dir)
486  {
487  return transform_line_dispatch(mln_trait_image_speed(I)(),
488  mln_trait_accumulator_when_pix(A)(),
489  a, input, length, dir);
490  }
491 
492  } // end of namespace mln::accu::internal
493 
494 
495 
496 
497  // Facades.
498 
499 
500  template <typename A, typename I>
501  inline
502  mln_ch_value(I, mln_result(A))
503  transform_line(const Accumulator<A>& a,
504  const Image<I>& input,
505  unsigned length, unsigned dir)
506  {
507  mln_trace("accu::transform_line");
508 
509  internal::transform_line_tests(a, input);
510 
511  extension::adjust(input, length / 2); // Safety.
512 
513  mln_ch_value(I, mln_result(A)) output;
514  output = internal::transform_line_dispatch(a, input, length, dir);
515 
516  return output;
517  }
518 
519 
520  template <typename A, typename I>
521  inline
522  mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
523  transform_line(const Meta_Accumulator<A>& a,
524  const Image<I>& input,
525  unsigned length, unsigned dir)
526  {
527  mln_trace("accu::transform_line");
528 
529  typedef mln_accu_with(A, mln_value(I)) A_;
530  A_ a_ = accu::unmeta(exact(a), mln_value(I)());
531 
532  internal::transform_line_tests(a_, input);
533 
534  mln_ch_value(I, mln_result(A_)) output;
535  output = internal::transform_line_dispatch(a_, input, length, dir);
536 
537  return output;
538  }
539 
540 
541 # endif // ! MLN_INCLUDE_ONLY
542 
543  } // end of namespace mln::accu
544 
545 } // end of namespace mln
546 
547 
548 #endif // ! MLN_ACCU_TRANSFORM_LINE_HH