Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
labeling/compute.hh
1 // Copyright (C) 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 #ifndef MLN_LABELING_COMPUTE_HH
28 # define MLN_LABELING_COMPUTE_HH
29 
47 
48 # include <mln/core/concept/image.hh>
49 # include <mln/core/concept/accumulator.hh>
50 # include <mln/core/concept/meta_accumulator.hh>
51 # include <mln/util/array.hh>
52 # include <mln/convert/from_to.hh>
53 # include <mln/geom/ncols.hh>
54 # include <mln/value/next.hh>
55 
56 
57 namespace mln
58 {
59 
60  namespace labeling
61  {
62 
71  //
72  template <typename A, typename I, typename L>
73  util::array<mln_result(A)>
74  compute(const Accumulator<A>& a,
75  const Image<I>& input,
76  const Image<L>& label,
77  const mln_value(L)& nlabels);
78 
79 
88  //
89  template <typename A, typename I, typename L>
90  util::array<mln_meta_accu_result(A, mln_value(I))>
91  compute(const Meta_Accumulator<A>& a,
92  const Image<I>& input,
93  const Image<L>& label,
94  const mln_value(L)& nlabels);
95 
96 
104  //
105  template <typename A, typename L>
106  util::array<mln_result(A)>
107  compute(const Accumulator<A>& a,
108  const Image<L>& label,
109  const mln_value(L)& nlabels);
110 
111 
119  //
120  template <typename A, typename L>
121  util::array<mln_meta_accu_result(A, mln_psite(L))>
122  compute(const Meta_Accumulator<A>& a,
123  const Image<L>& label,
124  const mln_value(L)& nlabels);
125 
126 
135  //
136  template <typename A, typename I, typename L>
137  util::array<mln_result(A)>
138  compute(util::array<A>& a,
139  const Image<I>& input,
140  const Image<L>& label,
141  const mln_value(L)& nlabels);
142 
143 
144 
145 # ifndef MLN_INCLUDE_ONLY
146 
147  namespace internal
148  {
149 
150  template <typename A, typename L>
151  inline
152  void
153  compute_tests(const Accumulator<A>& a,
154  const Image<L>& label,
155  const mln_value(L)& nlabels)
156  {
157  mln_precondition(exact(label).is_valid());
158  // mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
159  (void) a;
160  (void) label;
161  (void) nlabels;
162  }
163 
164 
165  template <typename A, typename I, typename L>
166  inline
167  void
168  compute_tests(const Accumulator<A>& a,
169  const Image<I>& input,
170  const Image<L>& label,
171  const mln_value(L)& nlabels)
172  {
173  mln_precondition(exact(input).is_valid());
174  mln_precondition(exact(label).is_valid());
175  // mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
176  (void) a;
177  (void) input;
178  (void) label;
179  (void) nlabels;
180  }
181 
182  } // end of namespace mln::labeling::internal
183 
184 
185 
186  namespace impl
187  {
188 
189  namespace generic
190  {
191 
192 
200  //
201  template <typename A, typename L>
202  inline
203  util::array<mln_result(A)>
205  const Image<L>& label_,
206  const mln_value(L)& nlabels)
207  {
208  trace::entering("labeling::impl::generic::compute");
209  internal::compute_tests(a_, label_, nlabels);
210 
211  const A& a = exact(a_);
212  const L& label = exact(label_);
213 
214  util::array<A> accus(value::next(nlabels), a);
215 
216  mln_piter(L) p(label.domain());
217  for_all(p)
218  accus[label(p)].take(p);
219 
221  convert::from_to(accus, res);
222 
223  trace::exiting("labeling::impl::generic::compute");
224  return res;
225  }
226 
237  //
238  template <typename A, typename L>
239  inline
242  const Image<L>& label_,
243  const mln_value(L)& nlabels)
244  {
245  trace::entering("labeling::impl::generic::compute");
246  internal::compute_tests(A(), label_, nlabels);
247 
248  if (value::next(nlabels) != accus.size())
249  {
250  accus.resize(0); // Make sure all the accumulators are
251  // re-initialized when resizing on next
252  // line.
253  accus.resize(value::next(nlabels));
254  }
255 
256  const L& label = exact(label_);
257 
258  mln_piter(L) p(label.domain());
259  for_all(p)
260  accus[label(p)].take(p);
261 
263  convert::from_to(accus, res);
264 
265  trace::exiting("labeling::impl::generic::compute");
266  return res;
267  }
268 
269 
270 
279  //
280  template <typename A, typename I, typename L>
281  inline
284  const Image<I>& input_,
285  const Image<L>& label_,
286  const mln_value(L)& nlabels)
287  {
288  trace::entering("labeling::impl::generic::compute");
289  internal::compute_tests(a_, input_, label_, nlabels);
290 
291  const A& a = exact(a_);
292  const I& input = exact(input_);
293  const L& label = exact(label_);
294 
295  util::array<A> accus(value::next(nlabels), a);
296 
297  mln_piter(I) p(input.domain());
298  for_all(p)
299  accus[label(p)].take(input(p));
300 
302  convert::from_to(accus, res);
303 
304  trace::exiting("labeling::impl::generic::compute");
305  return res;
306  }
307 
308 
317  //
318  template <typename A, typename I, typename L>
319  inline
322  const Image<I>& input_,
323  const Image<L>& label_,
324  const mln_value(L)& nlabels)
325  {
326  trace::entering("labeling::impl::generic::compute");
327  //internal::compute_tests(a_, input_, label_, nlabels);
328 
329  //const A& a = exact(a_);
330  const I& input = exact(input_);
331  const L& label = exact(label_);
332  (void) nlabels;
333 
334  if (value::next(nlabels) != accus.size())
335  {
336  accus.resize(0); // Make sure all the accumulators are
337  // re-initialized when resizing on next
338  // line.
339  accus.resize(value::next(nlabels));
340  }
341 
342  mln_piter(I) p(input.domain());
343  for_all(p)
344  accus[label(p)].take(input(p));
345 
347  convert::from_to(accus, res);
348 
349  trace::exiting("labeling::impl::generic::compute");
350  return res;
351  }
352 
353  } // end of namespace mln::labeling::impl::generic
354 
355 
356 
357  // FIXME: is there any optimization if border::get(input) ==
358  // border::get(label)) ?
359  //
360 
369  //
370  template <typename A, typename I, typename L>
371  inline
374  const Image<I>& input_,
375  const Image<L>& label_,
376  const mln_value(L)& nlabels)
377  {
378  trace::entering("labeling::impl::compute_fastest");
379  internal::compute_tests(a_, input_, label_, nlabels);
380 
381  const A& a = exact(a_);
382  const I& input = exact(input_);
383  const L& label = exact(label_);
384 
385  // FIXME: check image properties + add doc.
386 
387  util::array<A> accus(value::next(nlabels), a);
388 
389  unsigned ncols = geom::ncols(label);
390 
391  typedef mln_site(I) P;
392  typedef const mln_value(I) * iptr_t;
393  typedef const mln_value(L) * lptr_t;
394  box_runstart_piter<P> p(label.domain());
395  for_all(p)
396  {
397  iptr_t iptr = & input(p);
398  lptr_t lptr = & label(p);
399 
400  for (unsigned i = 0; i < ncols; ++i)
401  accus[*lptr++].take(*iptr++);
402  }
403 
405  convert::from_to(accus, res);
406 
407  trace::exiting("labeling::impl::generic::compute_fastest");
408  return res;
409  }
410 
411  // FIXME: is there any optimization if border::get(input) ==
412  // border::get(label)) ?
413  //
414 
423  //
424  template <typename A, typename I, typename L>
425  inline
428  const Image<I>& input_,
429  const Image<L>& label_,
430  const mln_value(L)& nlabels)
431  {
432  trace::entering("labeling::impl::generic::compute_fastest");
433  //internal::compute_tests(a_, input_, label_, nlabels);
434 
435  // FIXME: check image properties + add doc.
436 
437  //const A& a = exact(a_);
438  const I& input = exact(input_);
439  const L& label = exact(label_);
440  (void) nlabels;
441 
442  if (value::next(nlabels) != accus.size())
443  {
444  accus.resize(0); // Make sure all the accumulators are
445  // re-initialized when resizing on next
446  // line.
447  accus.resize(value::next(nlabels));
448  }
449 
450  unsigned ncols = geom::ncols(label);
451 
452  typedef mln_site(I) P;
453  typedef const mln_value(I) * iptr_t;
454  typedef const mln_value(L) * lptr_t;
455  box_runstart_piter<P> p(label.domain());
456  for_all(p)
457  {
458  iptr_t iptr = & input(p);
459  lptr_t lptr = & label(p);
460 
461  for (unsigned i = 0; i < ncols; ++i)
462  accus[*lptr++].take(*iptr++);
463  }
464 
466  convert::from_to(accus, res);
467 
468  trace::exiting("labeling::impl::generic::compute_fastest");
469  return res;
470  }
471 
472 
473 
474  } // end of namespace mln::labeling::impl
475 
476 
477 
478  namespace internal
479  {
480 
481 
482  template <typename A, typename L>
483  inline
485  compute_dispatch(const Accumulator<A>& a,
486  const Image<L>& label,
487  const mln_value(L)& nlabels)
488  {
489  return impl::generic::compute(a, label, nlabels);
490  }
491 
492 
493 
494 
495 
496  template <typename A, typename I, typename L>
497  inline
498  util::array<mln_result(A)>
499  compute_dispatch(
500  mln::trait::image::value_access::any,
501  mln::trait::image::value_access::any,
502  mln::trait::image::ext_domain::any,
503  mln::trait::image::ext_domain::any,
504  const Accumulator<A>& a,
505  const Image<I>& input,
506  const Image<L>& label,
507  const mln_value(L)& nlabels)
508  {
509  return impl::generic::compute(a, input, label, nlabels);
510  }
511 
512 
513  template <typename A, typename I, typename L>
514  inline
515  util::array<mln_result(A)>
516  compute_dispatch(
517  mln::trait::image::value_access::direct,
518  mln::trait::image::value_access::direct,
519  mln::trait::image::ext_domain::some,
520  mln::trait::image::ext_domain::some,
521  const Accumulator<A>& a,
522  const Image<I>& input,
523  const Image<L>& label,
524  const mln_value(L)& nlabels)
525  {
526  return impl::compute_fastest(a, input, label, nlabels);
527  }
528 
529 
530  template <typename A, typename I, typename L>
531  inline
532  util::array<mln_result(A)>
533  compute_dispatch(mln::trait::image::value_storage::any,
534  mln::trait::image::value_storage::any,
535  const Accumulator<A>& a,
536  const Image<I>& input,
537  const Image<L>& label,
538  const mln_value(L)& nlabels)
539  {
540  return impl::generic::compute(a, input, label, nlabels);
541  }
542 
543 
544  template <typename A, typename I, typename L>
545  inline
546  util::array<mln_result(A)>
547  compute_dispatch(mln::trait::image::value_storage::one_block,
548  mln::trait::image::value_storage::one_block,
549  const Accumulator<A>& a,
550  const Image<I>& input_,
551  const Image<L>& label_,
552  const mln_value(L)& nlabels)
553  {
554  const I& input = exact(input_);
555  const L& label = exact(label_);
556 
558  if (mlc_is(mln_trait_image_value_alignment(I),
559  trait::image::value_alignment::with_grid)::value &&
560  mlc_is(mln_trait_image_value_alignment(L),
561  trait::image::value_alignment::with_grid)::value)
562  {
563  return compute_dispatch(
564  mln_trait_image_value_access(I)(),
565  mln_trait_image_value_access(L)(),
566  mln_trait_image_ext_domain(I)(),
567  mln_trait_image_ext_domain(L)(),
568  a, input, label, nlabels);
569  }
570  else
571  return impl::generic::compute(a, input, label, nlabels);
572  }
573 
574 
575  template <typename A, typename I, typename L>
576  inline
577  util::array<mln_result(A)>
578  compute_dispatch(const Accumulator<A>& a,
579  const Image<I>& input,
580  const Image<L>& label,
581  const mln_value(L)& nlabels)
582  {
583  return compute_dispatch(mln_trait_image_value_storage(I)(),
584  mln_trait_image_value_storage(L)(),
585  a, input, label, nlabels);
586  }
587 
588 
589 
590 
591 
592 
593 
594 
595  template <typename A, typename I, typename L>
596  inline
597  util::array<mln_result(A)>
598  compute_dispatch(
599  mln::trait::image::value_access::any,
600  mln::trait::image::value_access::any,
601  mln::trait::image::ext_domain::any,
602  mln::trait::image::ext_domain::any,
603  util::array<A>& a,
604  const Image<I>& input,
605  const Image<L>& label,
606  const mln_value(L)& nlabels)
607  {
608  return impl::generic::compute(a, input, label, nlabels);
609  }
610 
611 
612  template <typename A, typename I, typename L>
613  inline
614  util::array<mln_result(A)>
615  compute_dispatch(
616  mln::trait::image::value_access::direct,
617  mln::trait::image::value_access::direct,
618  mln::trait::image::ext_domain::some,
619  mln::trait::image::ext_domain::some,
620  util::array<A>& a,
621  const Image<I>& input,
622  const Image<L>& label,
623  const mln_value(L)& nlabels)
624  {
625  return impl::compute_fastest(a, input, label, nlabels);
626  }
627 
628 
629  template <typename A, typename I, typename L>
630  inline
631  util::array<mln_result(A)>
632  compute_dispatch(mln::trait::image::value_storage::one_block,
633  mln::trait::image::value_storage::one_block,
634  util::array<A>& a,
635  const Image<I>& input_,
636  const Image<L>& label_,
637  const mln_value(L)& nlabels)
638  {
639  const I& input = exact(input_);
640  const L& label = exact(label_);
641 
643  if (mlc_is(mln_trait_image_value_alignment(I),
644  trait::image::value_alignment::with_grid)::value &&
645  mlc_is(mln_trait_image_value_alignment(L),
646  trait::image::value_alignment::with_grid)::value)
647  {
648  return compute_dispatch(
649  mln_trait_image_value_access(I)(),
650  mln_trait_image_value_access(L)(),
651  mln_trait_image_ext_domain(I)(),
652  mln_trait_image_ext_domain(L)(),
653  a, input, label, nlabels);
654  }
655  else
656  return impl::generic::compute(a, input, label, nlabels);
657  }
658 
659 
660  template <typename A, typename I, typename L>
661  inline
662  util::array<mln_result(A)>
663  compute_dispatch(util::array<A>& a,
664  const Image<I>& input,
665  const Image<L>& label,
666  const mln_value(L)& nlabels)
667  {
668  return compute_dispatch(mln_trait_image_value_storage(I)(),
669  mln_trait_image_value_storage(L)(),
670  a, input, label, nlabels);
671  }
672 
673 
674 
675 
676 
677  template <typename A, typename L>
678  inline
679  util::array<mln_result(A)>
680  compute_dispatch(util::array<A>& accus,
681  const Image<L>& label,
682  const mln_value(L)& nlabels)
683  {
684  return impl::generic::compute(accus, label, nlabels);
685  }
686 
687  } // end of namespace mln::labeling::internal
688 
689 
690 
691  // Facades.
692 
693  template <typename A, typename I, typename L>
694  inline
695  util::array<mln_result(A)>
697  const Image<I>& input,
698  const Image<L>& label,
699  const mln_value(L)& nlabels)
700  {
701  trace::entering("labeling::compute");
702 
703  //internal::compute_tests(a, input, label, nlabels);
704 
705  typedef util::array<mln_result(A)> R;
706  R res = internal::compute_dispatch(a, input, label, nlabels);
707 
708  trace::exiting("labeling::compute");
709  return res;
710  }
711 
712  template <typename A, typename I, typename L>
713  inline
716  const Image<I>& input,
717  const Image<L>& label,
718  const mln_value(L)& nlabels)
719  {
720  trace::entering("labeling::compute");
721 
722  internal::compute_tests(a, input, label, nlabels);
723 
724  typedef util::array<mln_result(A)> R;
725  R res = internal::compute_dispatch(a, input, label, nlabels);
726 
727  trace::exiting("labeling::compute");
728  return res;
729  }
730 
731  template <typename A, typename I, typename L>
732  inline
735  const Image<I>& input,
736  const Image<L>& label,
737  const mln_value(L)& nlabels)
738  {
739  typedef mln_accu_with(A, mln_value(I)) A_;
740  A_ a_ = accu::unmeta(exact(a), mln_value(I)());
741 
742  return compute(a_, input, label, nlabels);
743  }
744 
745 
746  template <typename A, typename L>
747  inline
749  compute(util::array<A>& accus,
750  const Image<L>& label,
751  const mln_value(L)& nlabels)
752  {
753  trace::entering("labeling::compute");
754 
755  internal::compute_tests(A(), label, nlabels);
756 
757  typedef util::array<mln_result(A)> R;
758  R res = internal::compute_dispatch(accus, label, nlabels);
759 
760  mln_postcondition(res.nelements() == value::next(nlabels));
761 
762  trace::exiting("labeling::compute");
763  return res;
764  }
765 
766 
767 
768  template <typename A, typename L>
769  inline
770  util::array<mln_result(A)>
772  const Image<L>& label,
773  const mln_value(L)& nlabels)
774  {
775  trace::entering("labeling::compute");
776 
777  internal::compute_tests(a, label, nlabels);
778 
779  typedef util::array<mln_result(A)> R;
780  R res = internal::compute_dispatch(a, label, nlabels);
781 
782  mln_postcondition(res.nelements() == value::next(nlabels));
783 
784  trace::exiting("labeling::compute");
785  return res;
786  }
787 
788 
789  template <typename A, typename L>
790  inline
793  const Image<L>& label,
794  const mln_value(L)& nlabels)
795  {
796  typedef mln_accu_with(A, mln_psite(L)) A_;
797  A_ a_ = accu::unmeta(exact(a), mln_psite(L)());
798 
799  return compute(a_, label, nlabels);
800  }
801 
802 
803 # endif // ! MLN_INCLUDE_ONLY
804 
805  } // end of namespace mln::labeling
806 
807 } // end of namespace mln
808 
809 
810 #endif // ! MLN_LABELING_COMPUTE_HH