$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
component_set.hh
1 // Copyright (C) 2009, 2010, 2011, 2013 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 SCRIBO_CORE_COMPONENT_SET_HH
28 # define SCRIBO_CORE_COMPONENT_SET_HH
29 
36 
37 # include <mln/core/concept/site_set.hh>
38 # include <mln/core/concept/function.hh>
39 
40 # include <mln/data/fill.hh>
41 
42 # include <mln/util/array.hh>
43 # include <mln/value/next.hh>
44 
45 # include <mln/accu/pair.hh>
46 # include <mln/accu/center.hh>
47 # include <mln/accu/shape/bbox.hh>
48 
49 # include <mln/labeling/compute.hh>
50 # include <mln/labeling/relabel.hh>
51 
52 # include <mln/logical/or.hh>
53 
54 # include <mln/convert/from_to.hh>
55 
56 # include <mln/core/image/dmorph/image_if.hh>
57 # include <mln/pw/all.hh>
58 
59 # include <mln/core/routine/duplicate.hh>
60 
61 # include <mln/value/next.hh>
62 
63 # include <scribo/core/macros.hh>
64 # include <scribo/core/component_info.hh>
65 # include <scribo/core/concept/serializable.hh>
66 
67 
68 namespace scribo
69 {
70 
71  // Forward declaration.
72  template <typename L> class component_set;
73 
74 
75  namespace internal
76  {
81  template <typename L>
83  {
87 
88  typedef std::pair<mln_box(L),
89  std::pair<mln_site(L), unsigned> > pair_data_t;
90 
91  typedef mln_result(center_accu_t) center_t;
92 
94  component_set_data(const L& ima, const mln_value(L)& ncomps);
95  component_set_data(const L& ima, const mln_value(L)& ncomps,
96  const mln::util::array<pair_accu_t>& attribs,
98  component_set_data(const L& ima, const mln_value(L)& ncomps,
99  const mln::util::array<pair_data_t>& attribs,
101 
102  component_set_data(const L& ima, const mln_value(L)& ncomps,
104 
105  void fill_infos(const mln::util::array<pair_accu_t>& attribs,
107 
108  void fill_infos(const mln::util::array<pair_data_t>& attribs,
110 
111  // Useful while constructing incrementaly (XML loading).
112  void soft_init(const mln_value(L) ncomps);
113 
114  L ima_;
115  mln_value(L) ncomps_;
117 
118  mln_ch_value(L, bool) separators_;
119  };
120 
121  } // end of namespace scribo::internal
122 
123 
190 
216  template <typename L>
217  class component_set : public Serializable<component_set<L> >
218  {
222 
223  typedef std::pair<mln_box(L),
224  std::pair<mln_site(L), unsigned> > pair_data_t;
225 
226  typedef mln_result(center_accu_t) center_t;
227 
229  typedef data_t* id_t;
230 
231  public:
232 
233  // Constructors
234 
236  component_set();
237 
240 
243  component_set(const L& ima, const mln_value(L)& ncomps);
244 
247  component_set(const L& ima, const mln_value(L)& ncomps,
248  const mln::util::array<pair_accu_t>& attribs,
250 
253  component_set(const L& ima, const mln_value(L)& ncomps,
254  const mln::util::array<pair_data_t>& attribs,
256 
257  // Misc Members
258 
260  mln_value(L) nelements() const;
261 
263  const component_info<L>& info(const mln_value(L)& id) const;
264 
266  component_info<L>& info(const mln_value(L)& id);
267 
270 
272  const component_info<L>& operator()(const component_id_t& id) const;
273 
274 
277  template <typename F>
278  void update_tags(const mln::Function_v2b<F>& f, component::Tag tag);
279 
281  component_set<L> duplicate() const;
282 
284  const L& labeled_image() const;
285 
289  bool is_valid() const;
290 
291 
292  // Separators components related routines.
293 
295  bool has_separators() const;
296 
299  void add_separators(const mln_ch_value(L, bool)& ima);
300 
302  const mln_ch_value(L, bool)& separators() const;
303 
305  void clear_separators();
306 
307 
308  // Internal methods
309 
311 
314  //
315  const mln::util::array<scribo::component_info<L> >& infos_() const;
316 
319  //
320  id_t id_() const;
321 
322 
328  //
329  L& labeled_image_();
330 
337  //
338  void update_labeled_image_(const L& lbl);
339 
345  //
346  mln_concrete(L) valid_comps_image_() const;
347 
349 
350  protected:
353  void init_(const component_set<L>& model);
355 
357  };
358 
359 
361  template <typename L>
362  bool
363  operator==(const component_set<L>& lhs, const component_set<L>& rhs);
364 
366  template <typename L>
367  std::ostream&
368  operator<<(std::ostream& ostr, const component_set<L>& info);
369 
370 
371 
372 
373 # ifndef MLN_INCLUDE_ONLY
374 
375 
376  // component_set_data<L> >
377 
378  namespace internal
379  {
380 
381  // data< component_set<L> >
382 
383 
384  template <typename L>
385  inline
386  component_set_data<L>::component_set_data()
387  {
388  }
389 
390 
391  template <typename L>
392  inline
393  component_set_data<L>::component_set_data(const L& ima,
394  const mln_value(L)& ncomps)
395  : ima_(ima), ncomps_(ncomps)
396  {
397  }
398 
399 
400  template <typename L>
401  inline
402  void
403  component_set_data<L>::soft_init(const mln_value(L) ncomps)
404  {
405  mln_precondition(infos_.nelements() == 0);
406 
407  ncomps_ = ncomps;
408  infos_.reserve(mln::value::next(ncomps_));
409  infos_.append(component_info<L>()); // Component 0, i.e. the background.
410  }
411 
412 
413  } // end of namespace mln::internal
414 
415 
416 
417 
418  template <typename L>
419  inline
420  component_set<L>::component_set()
421  {
422  }
423 
424  template <typename L>
425  inline
426  component_set<L>::component_set(const mln::util::tracked_ptr<data_t>& data)
427  {
428  data_ = data;
429  }
430 
431  template <typename L>
432  inline
433  component_set<L>::component_set(const L& ima, const mln_value(L)& ncomps)
434  {
435  data_ = new internal::component_set_data<L>(ima, ncomps);
436 
437  initialize(data_->separators_, ima); // FIXME: to be removed
438  mln::data::fill(data_->separators_, false);
439 
440  typedef mln::accu::shape::bbox<mln_site(L)> bbox_accu_t;
441  typedef mln::accu::center<mln_site(L)> center_accu_t;
443 
444 
446  mln::labeling::compute(attribs, ima, ncomps);
447 
448 
449  typedef mln_site(L) P;
450 
451  data_->infos_.reserve(mln::value::next(ncomps));
452 
453  data_->infos_.append(component_info<L>()); // Component 0, i.e. the background.
454  for_all_comp_data(i, attribs)
455  {
456  component_info<L> info(i, attribs[i].first(),
457  attribs[i].second(), attribs[i].second_accu().nsites());
458  data_->infos_.append(info);
459  }
460  }
461 
462 
463  template <typename L>
464  inline
465  component_set<L>::component_set(const L& ima, const mln_value(L)& ncomps,
466  const mln::util::array<pair_accu_t>& attribs,
467  component::Type type)
468  {
469  data_ = new internal::component_set_data<L>(ima, ncomps);
470 
471  initialize(data_->separators_, ima); // FIXME: to be removed
472  mln::data::fill(data_->separators_, false);
473 
474  typedef mln_site(L) P;
475 
476  data_->infos_.reserve(mln::value::next(ncomps));
477 
478  data_->infos_.append(component_info<L>()); // Component 0, i.e. the background.
479  for_all_comp_data(i, attribs)
480  {
481  component_info<L> info(i, attribs[i].first(),
482  attribs[i].second(), attribs[i].second_accu().nsites(),
483  type);
484  data_->infos_.append(info);
485  }
486  }
487 
488 
489  template <typename L>
490  inline
491 
492  component_set<L>::component_set(const L& ima, const mln_value(L)& ncomps,
493  const mln::util::array<pair_data_t>& attribs,
494  component::Type type)
495  {
496  data_ = new internal::component_set_data<L>(ima, ncomps);
497 
498  initialize(data_->separators_, ima); // FIXME: to be removed
499  mln::data::fill(data_->separators_, false);
500 
501  typedef mln_site(L) P;
502 
503  data_->infos_.reserve(mln::value::next(ncomps));
504 
505  data_->infos_.append(component_info<L>()); // Component 0, i.e. the background.
506  for_all_comp_data(i, attribs)
507  {
508  component_info<L> info(i, attribs[i].first,
509  attribs[i].second.first, attribs[i].second.second,
510  type);
511  data_->infos_.append(info);
512  }
513  }
514 
515 
516  template <typename L>
517  inline
518 
519  mln_value(L)
520  component_set<L>::nelements() const
521  {
522  return data_->ncomps_;
523  }
524 
525  template <typename L>
526  inline
527  const component_info<L>&
528  component_set<L>::info(const mln_value(L)& id) const
529  {
530  return data_->infos_[id];
531  }
532 
533  template <typename L>
534  inline
535  component_info<L>&
536  component_set<L>::info(const mln_value(L)& id)
537  {
538  return data_->infos_[id];
539  }
540 
541  template <typename L>
542  inline
543  const component_info<L>&
544  component_set<L>::operator()(const component_id_t& id) const
545  {
546  return data_->infos_[id];
547  }
548 
549  template <typename L>
550  inline
551  component_info<L>&
552  component_set<L>::operator()(const component_id_t& id)
553  {
554  return data_->infos_[id];
555  }
556 
557 
558  template <typename L>
559  template <typename F>
560  inline
561  void
562  component_set<L>::update_tags(const mln::Function_v2b<F>& f_,
563  component::Tag tag)
564  {
565  const F& f = exact(f_);
566 
567  for_all_comp_data(i, data_->infos_)
568  if (!f(i))
569  data_->infos_[i].update_tag(tag);
570  }
571 
572 
573  template <typename L>
574  inline
575  component_set<L>
576  component_set<L>::duplicate() const
577  {
578  component_set<L> output;
579  output.init_(*this);
580  return output;
581  }
582 
583 
584 
585  template <typename L>
586  inline
587  const L&
588  component_set<L>::labeled_image() const
589  {
590  return data_->ima_;
591  }
592 
593 
594  template <typename L>
595  inline
596  void
597  component_set<L>::update_labeled_image_(const L& lbl)
598  {
599  data_->ima_ = lbl;
600  }
601 
602 
603  template <typename L>
604  inline
605  bool
606  component_set<L>::is_valid() const
607  {
608  return data_ != 0 && data_->ima_.is_valid();
609  }
610 
611 
612  template <typename L>
613  inline
614  typename component_set<L>::id_t
615  component_set<L>::id_() const
616  {
617  return data_.ptr_;
618  }
619 
620 
621  template <typename L>
622  inline
623  L&
624  component_set<L>::labeled_image_()
625  {
626  return data_->ima_;
627  }
628 
629 
630  template <typename L>
631  inline
632  mln_concrete(L)
633  component_set<L>::valid_comps_image_() const
634  {
635  mln::util::array<bool> f(mln::value::next(data_->ncomps_));
636  f(0) = true;
637 
638  for_all_comps(c, (*this))
639  f(c) = (*this)(c).is_valid();
640 
641  mln_value(L) new_ncomps;
642  mln_concrete(L)
643  output = mln::labeling::relabel(data_->ima_,
644  data_->ncomps_,
645  new_ncomps,
646  f);
647 
648  return output;
649  }
650 
651 
652  template <typename L>
653  inline
654  bool
655  component_set<L>::has_separators() const
656  {
657  return data_->separators_.is_valid();
658  }
659 
660 
661  template <typename L>
662  inline
663  void
664  component_set<L>::add_separators(const mln_ch_value(L, bool)& ima)
665  {
666  if (! has_separators())
667  data_->separators_ = ima;
668  else
669  mln::logical::or_inplace(data_->separators_, ima);
670  }
671 
672 
673  template <typename L>
674  inline
675  const mln_ch_value(L, bool)&
677  {
678  return data_->separators_;
679  }
680 
681 
682  template <typename L>
683  inline
684  void
685  component_set<L>::clear_separators()
686  {
687  data_->separators_.destroy();
688  }
689 
690 
691  template <typename L>
692  inline
694  component_set<L>::infos_() const
695  {
696  return data_->infos_;
697  }
698 
699  template <typename L>
700  inline
701  void
702  component_set<L>::init_(const component_set<L>& set)
703  {
704  data_ = new internal::component_set_data<L>();
705  data_->ima_ = mln::duplicate(set.labeled_image());
706  data_->ncomps_ = set.nelements();
707  data_->infos_ = set.infos_();
708  data_->separators_ = set.separators();
709  }
710 
711 
712  template <typename L>
713  bool
714  operator==(const component_set<L>& lhs, const component_set<L>& rhs)
715  {
716  if (lhs.id_() == rhs.id_())
717  return true;
718 
719  if (! (lhs.labeled_image() == rhs.labeled_image()))
720  return false;
721 
722  if (! (lhs.separators() == rhs.separators()))
723  return false;
724 
725  if (! (lhs.nelements() == rhs.nelements()
726  && lhs.labeled_image() == rhs.labeled_image()
727  && lhs.separators() == rhs.separators()))
728  return false;
729 
730  for_all_comps(c, lhs)
731  if (! (lhs(c) == rhs(c)))
732  return false;
733 
734  return true;
735  }
736 
737  template <typename L>
738  std::ostream&
739  operator<<(std::ostream& ostr, const component_set<L>& info)
740  {
741  ostr << "component_set[" << std::endl;
742  for_all_comps(i, info)
743  ostr << info(i);
744  ostr << "]" << std::endl;
745 
746  return ostr;
747  }
748 
749 # endif // ! MLN_INCLUDE_ONLY
750 
751 } // end of namespace scribo
752 
753 #endif // ! SCRIBO_CORE_COMPONENT_SET_HH