$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
value_and_compute.hh
1 // Copyright (C) 2010, 2012, 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 MLN_LABELING_VALUE_AND_COMPUTE_HH
28 # define MLN_LABELING_VALUE_AND_COMPUTE_HH
29 
33 
34 # include <mln/core/concept/image.hh>
35 # include <mln/core/concept/neighborhood.hh>
36 # include <mln/canvas/labeling/video.hh>
37 # include <mln/data/fill.hh>
38 # include <mln/util/array.hh>
39 # include <mln/util/couple.hh>
40 
41 
42 
43 namespace mln
44 {
45 
46  namespace labeling
47  {
48 
61  template <typename I, typename N, typename L, typename A>
62  util::couple<mln_ch_value(I,L),
63  util::couple<util::array<mln_result(A)>,
64  util::array<A> > >
65  value_and_compute(const Image<I>& input, const mln_value(I)& val,
66  const Neighborhood<N>& nbh, L& nlabels,
67  const Accumulator<A>& accu);
68 
69 
70 # ifndef MLN_INCLUDE_ONLY
71 
72 
73  // Tests.
74 
75  namespace internal
76  {
77 
78  template <typename I, typename N, typename L, typename A>
79  void
80  value_and_compute_tests(const Image<I>& input,
81  const mln_value(I)& /* val */,
82  const Neighborhood<N>& nbh, L& /* nlabels */,
83  const Accumulator<A>& /* accu */)
84  {
85  mln_precondition(exact(input).is_valid());
86  mln_precondition(exact(nbh).is_valid());
87 
88  (void) input;
89  (void) nbh;
90  }
91 
92  } // end of namespace mln::labeling::internal
93 
94 
95 
96  namespace impl
97  {
98 
99  // Generic functor.
100 
101  template <typename I, typename L, typename A>
102  struct value_and_compute_functor
103  {
104  typedef mln_psite(I) P;
105 
106  util::array<mln_result(A)> result_;
107  util::array<A> accus_;
108 
109  const I& input;
110  const mln_value(I)& val;
111 
112  typedef mln_result(A) accu_result;
113  typedef mln_argument(A) accu_argument;
114  typedef util::couple<util::array<accu_result>,
115  util::array<A> > result;
116 
117 
118  // Requirements from mln::canvas::labeling.
119 
120  typedef mln_domain(I) S;
121 
122  // Generic implementation
123 
124  void init() {}
125  bool handles(const P& p) const { return input(p) == val; }
126  bool equiv(const P& n, const P&) const { return input(n) == val; }
127  bool labels(const P&) const { return true; }
128  void do_no_union(const P&, const P&) {}
129  void init_attr(const P&) {}
130  void merge_attr(const P&, const P&) {}
131  void set_new_label(const P& p, const L& l)
132  {
133  accus_.append(A());
134  process__(accu_argument(), p, l);
135  }
136  void set_label(const P& p, const L& l) { process__(accu_argument(), p, l); };
137  void finalize() { convert::from_to(accus_, result_); }
138 
139 
140 
141  // Fastest implementation
142 
143  void init_() { accus_.append(A()); }
144  bool handles_(unsigned p) const { return input.element(p) == val; }
145  bool equiv_(unsigned n, unsigned) const { return input.element(n) == val; }
146  bool labels_(unsigned) const { return true; }
147  void do_no_union_(unsigned, unsigned) {}
148  void init_attr_(unsigned) {}
149  void merge_attr_(unsigned, unsigned) {}
150  void set_new_label_(unsigned p, const L& l)
151  {
152  accus_.append(A());
153  process__(accu_argument(), p, l);
154  };
155  void set_label_(unsigned p, const L& l) { process__(accu_argument(), p, l); };
156  void finalize_() { convert::from_to(accus_, result_); }
157 
158  // end of Requirements.
159 
160 
161 
162  value_and_compute_functor(const Image<I>& input_, const mln_value(I)& val)
163  : input(exact(input_)),
164  val(val)
165  {
166  }
167 
168 
169  private:
170  inline
171  void process__(const unsigned&, unsigned p, const L& l)
172  {
173  accus_[l].take(p);
174  }
175 
176  inline
177  void process__(const mln_psite(I)&, unsigned p, const L& l)
178  {
179  accus_[l].take(input.point_at_offset(p));
180  }
181 
182 
183  inline
184  void process__(const mln_psite(I)&, const mln_site(I)& p, const L& l)
185  {
186  accus_[l].take(p);
187  }
188 
189  inline
190  void process__(const mln_value(I)&, const mln_site(I)&, const L& l)
191  {
192  accus_[l].take(l);
193  }
194 
195  template <typename V>
196  inline
197  void process__(const V&, const mln_site(I)&, const L& /* l */)
198  {
199  mlc_abort(V)::check();
200  }
201 
202 
203  };
204 
205  } // end of namespace mln::labeling::impl
206 
207 
208 
209 
210  // Facade.
211 
212  template <typename I, typename N, typename L, typename A>
213  util::couple<mln_ch_value(I,L),
214  util::couple<util::array<mln_result(A)>,
215  util::array<A> > >
216  value_and_compute(const Image<I>& input, const mln_value(I)& val,
217  const Neighborhood<N>& nbh, L& nlabels,
218  const Accumulator<A>& accu)
219  {
220  mln_trace("labeling::value_and_compute");
221 
222  internal::value_and_compute_tests(input, val, nbh, nlabels, accu);
223 
224  typedef mln_ch_value(I,L) out_t;
225  typedef impl::value_and_compute_functor<I, L, A> func_t;
226  func_t f(input, val);
227  out_t output = canvas::labeling::video(input, nbh, nlabels, f);
228 
229  util::couple<out_t, typename func_t::result>
230  result = make::couple(output,
231  make::couple(f.result_, f.accus_));
232 
233 
234  return result;
235  }
236 
237 # endif // ! MLN_INCLUDE_ONLY
238 
239  } // end of namespace mln::labeling
240 
241 } // end of namespace mln
242 
243 
244 #endif // ! MLN_LABELING_VALUE_AND_COMPUTE_HH