Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
labeled_image_base.hh
1 // Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
2 // (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_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH
28 # define MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH
29 
33 
34 # include <mln/core/image/dmorph/image_if.hh>
35 # include <mln/core/concept/function.hh>
36 # include <mln/core/internal/image_identity.hh>
37 # include <mln/core/site_set/box.hh>
38 
39 # include <mln/accu/shape/bbox.hh>
40 
41 # include <mln/labeling/relabel.hh>
42 
43 # include <mln/util/array.hh>
44 # include <mln/value/next.hh>
45 
46 # include <mln/pw/cst.hh>
47 # include <mln/pw/value.hh>
48 
49 # include <mln/make/relabelfun.hh>
50 
51 
52 namespace mln
53 {
54 
55  // Forward declaration.
56  template <typename I, typename E>
57  class labeled_image_base;
58 
59 
60  namespace internal
61  {
62 
64  template <typename I, typename E>
65  struct data< labeled_image_base<I,E> >
66  {
67  data(const I& ima, const mln_value(I)& nlabels);
68  data(const I& ima, const mln_value(I)& nlabels,
69  const util::array<mln_box(I)>& bboxes);
70 
71  I ima_;
72  mln_value(I) nlabels_;
73  mutable util::array< box<mln_psite(I)> > bboxes_;
74  };
75 
76  } // end of namespace mln::internal
77 
78 
79 
80  namespace trait
81  {
82 
83  template <typename I, typename E>
84  struct image_< labeled_image_base<I,E> > : image_< I > // Same as I except...
85  {
86  // ...these changes.
87  typedef trait::image::category::identity_morpher category;
88  typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
89  typedef trait::image::value_access::indirect value_access;
90 
91  typedef trait::image::value_io::read_only value_io;
92  typedef trait::image::pw_io::read pw_io;
93 
94  // extended domain
95  typedef trait::image::ext_value::multiple ext_value;
96  typedef trait::image::ext_io::read_only ext_io;
97  };
98 
99  } // end of namespace mln::trait
100 
101 
102 
115  template <typename I, typename E>
117  : public internal::image_identity< const I, mln_domain(I), E >
118  {
119  typedef internal::image_identity< const I, mln_domain(I), E >
120  super_;
121 
122  public:
124  typedef mln_result(accu::shape::bbox<mln_psite(I)>) bbox_t;
125 
131 
134  //
138  // FIXME: currently the label is kept contiguous for
139  // performance reasons. Do we want to be less restrictive?
140  template <typename F>
141  void relabel(const Function_v2v<F>& f);
142  //
145  template <typename F>
146  void relabel(const Function_v2b<F>& f);
148 
150  mln_value(I) nlabels() const;
151 
153  const bbox_t& bbox(const mln_value(I)& label) const;
154 
156  const util::array<bbox_t>& bboxes() const;
157 
159  p_if<mln_box(I),
160  fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
161  subdomain(const mln_value(I)& label) const;
162 
163  protected:
165  void update_data(const fun::i2v::array<mln_value(I)>& relabel_fun);
166 
167  template <typename F>
168  void relabel_(const Function_v2v<F>& f);
169 
170  template <typename F>
171  void relabel_(const Function_v2b<F>& f);
172 
175  void init_update_data_();
176  void prepare_update_data_(const mln_value(I)& lbl,
177  const mln_value(I)& new_lbl);
178  void update_data_(const fun::i2v::array<mln_value(I)>& relabel_fun);
180  };
181 
182 
183 
184 
185 # ifndef MLN_INCLUDE_ONLY
186 
187 
188  // internal::data< labeled_image_base<I,E> >
189 
190  namespace internal
191  {
192 
193 
194  // data< labeled_image_base<I,E> >
195 
196  template <typename I, typename E>
197  inline
198  data< labeled_image_base<I,E> >::data(const I& ima, const mln_value(I)& nlabels)
199  : ima_(ima), nlabels_(nlabels)
200  {
201  }
202 
203  template <typename I, typename E>
204  inline
205  data< labeled_image_base<I,E> >::data(const I& ima, const mln_value(I)& nlabels,
206  const util::array<mln_box(I)>& bboxes)
207  : ima_(ima), nlabels_(nlabels), bboxes_(bboxes)
208  {
209  }
210 
211 
212  } // end of namespace mln::internal
213 
214 
215  template <typename I, typename E>
216  inline
218  {
219  }
220 
221 
222  template <typename I, typename E>
223  template <typename F>
224  inline
225  void
227  {
228  const F& f = exact(f_);
229  mln_value(I) new_nlabels;
230 
231  fun::i2v::array<mln_value(I)>
232  packed_relabel_fun = make::relabelfun(f,
233  this->data_->nlabels_,
234  new_nlabels);
235 
236  labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_,
237  packed_relabel_fun);
238 
239  this->data_->nlabels_ = new_nlabels;
240 
241  exact(this)->relabel_(f);
242 
244  update_data(packed_relabel_fun);
245  }
246 
247 
248  template <typename I, typename E>
249  template <typename F>
250  inline
251  void
253  {
254  const F& f = exact(f_);
255 
256  // Relabel the underlying image.
257  typedef fun::i2v::array<mln_value(I)> fv2v_t;
258  fv2v_t fv2v = make::relabelfun(f,
259  this->data_->nlabels_,
260  this->data_->nlabels_);
261 
262  labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_, fv2v);
263 
264  exact(this)->relabel_(f);
265 
266  // Then, merge or delete bounding boxes according to this relabeling.
267  update_data(fv2v);
268  }
269 
270  template <typename I, typename E>
271  inline
272  mln_value(I)
273  labeled_image_base<I,E>::nlabels() const
274  {
275  return this->data_->nlabels_;
276  }
277 
278 
279  template <typename I, typename E>
280  void
281  labeled_image_base<I,E>::update_data(const fun::i2v::array<mln_value(I)>& relabel_fun)
282  {
284  new_bboxes(mln::value::next(this->data_->nlabels_));
285 
286  exact(this)->init_update_data_();
287 
288  for (unsigned i = 1; i < this->data_->bboxes_.size(); ++i)
289  if (relabel_fun(i) != 0)
290  {
291  new_bboxes[relabel_fun(i)].take(this->data_->bboxes_[i]);
292  exact(this)->prepare_update_data_(i, relabel_fun(i));
293  }
294 
295  convert::from_to(new_bboxes, this->data_->bboxes_);
296 
297  mln_assertion(new_bboxes.size() == this->data_->bboxes_.size());
298 
299  exact(this)->update_data_(relabel_fun);
300  }
301 
302 
303  template <typename I, typename E>
304  const typename labeled_image_base<I,E>::bbox_t&
305  labeled_image_base<I,E>::bbox(const mln_value(I)& label) const
306  {
307  return this->data_->bboxes_[label];
308  }
309 
310 
311  template <typename I, typename E>
314  {
315  return this->data_->bboxes_;
316  }
317 
318 
319  template <typename I, typename E>
320  p_if<mln_box(I),
321  fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
322  labeled_image_base<I,E>::subdomain(const mln_value(I)& label) const
323  {
324  return ((this->data_->ima_ | bbox(label))
325  | (pw::value(this->data_->ima_) == pw::cst(label))).domain();
326  }
327 
328 
329 
330  template <typename I, typename E>
331  template <typename F>
332  void
334  {
335  (void) f;
336  // No-Op.
337  }
338 
339  template <typename I, typename E>
340  template <typename F>
341  void
342  labeled_image_base<I,E>::relabel_(const Function_v2b<F>& f)
343  {
344  (void) f;
345  // No-Op.
346  }
347 
348  template <typename I, typename E>
349  void
350  labeled_image_base<I,E>::update_data_(
351  const fun::i2v::array<mln_value(I)>& relabel_fun)
352  {
353  (void) relabel_fun;
354  // No-Op.
355  }
356 
357  template <typename I, typename E>
358  void
359  labeled_image_base<I,E>::prepare_update_data_(const mln_value(I)& lbl,
360  const mln_value(I)& new_lbl)
361  {
362  (void) lbl;
363  (void) new_lbl;
364  // No-Op.
365  }
366 
367  template <typename I, typename E>
368  void
369  labeled_image_base<I,E>::init_update_data_()
370  {
371  // No-Op.
372  }
373 
374 
375 # endif // ! MLN_INCLUDE_ONLY
376 
377 } // end of namespace mln
378 
379 
380 #endif // ! MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH