$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
core/w_window.hh
1 // Copyright (C) 2007, 2008, 2009, 2012, 2013 EPITA Research and
2 // Development 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_CORE_W_WINDOW_HH
28 # define MLN_CORE_W_WINDOW_HH
29 
35 
36 # include <map>
37 
38 # include <mln/core/internal/weighted_window_base.hh>
39 # include <mln/core/concept/image.hh>
40 # include <mln/core/site_set/box.hh>
41 # include <mln/core/window.hh>
42 # include <mln/core/dpsites_piter.hh>
43 
44 # include <mln/value/ops.hh>
45 # include <mln/util/ord.hh>
46 # include <mln/geom/bbox.hh> // FIXME: We may have some dep trouble with this include.
47 # include <mln/literal/zero.hh>
48 # include <mln/convert/to.hh>
49 
50 
51 namespace mln
52 {
53 
54  // Forward declarations.
55  template <typename D, typename W> struct w_window;
56  template <typename It, typename W> struct with_w_;
57 
58 
59  namespace trait
60  {
61 
62  template <typename D, typename W>
63  struct window_< mln::w_window<D,W> > : window_< mln::window<D> >
64  {
65  // Same traits as its corresponding window.
66  };
67 
68  } // end of namespace mln::trait
69 
70 
77  template <typename D, typename W>
78  struct w_window : public internal::weighted_window_base< mln::window<D>,
79  w_window<D,W> >
80  {
82  typedef D dpsite;
83 
85  typedef W weight;
86 
87 
90 
93 
94 
96  w_window();
97 
98 
100  w_window<D,W>& insert(const W& w, const D& d);
101 
102 
104  W w(unsigned i) const;
105 
107  const std::vector<W>& weights() const;
108 
109 
111  const std::vector<D>& std_vector() const;
112 
114  const mln::window<D>& win() const;
115 
116 
118  bool is_symmetric() const;
119 
121  void sym();
122 
124  void clear();
125 
126  protected:
127 
129  std::vector<W> wei_;
130  };
131 
132 
135  template <typename D, typename W>
136  std::ostream& operator<<(std::ostream& ostr, const w_window<D,W>& w_win);
137 
138 
141  template <typename D, typename Wl, typename Wr>
142  bool operator==(const w_window<D,Wl>& lhs, const w_window<D,Wr>& rhs);
143 
146  template <typename D, typename W, typename I>
147  void from_to_(const w_window<D,W>& from, Image<I>& to);
148 
150  template <typename V, unsigned S, typename D, typename W>
151  void from_to_(const V (&weight)[S], w_window<D,W>& to);
153 
154 
155 
157  template <typename It, typename W>
158  struct with_w_ : public It
159  {
160 
161  template <typename Ds, typename P>
162  with_w_(const Ds& ds, const P& p);
163 
164  W w() const;
165 
166  protected:
167  const std::vector<W> wei_;
168  };
169 
170 
171 
172 # ifndef MLN_INCLUDE_ONLY
173 
174 
175  // with_w_<It,W>
176 
177  template <typename It, typename W>
178  template <typename Ds, typename P>
179  inline
180  with_w_<It,W>::with_w_(const Ds& ds,
181  const P& p)
182  : It(ds, p),
183  wei_(ds.weights())
184  {
185  }
186 
187  template <typename It, typename W>
188  inline
189  W
190  with_w_<It,W>::w() const
191  {
192  mln_precondition(this->i_ < wei_.size());
193  return wei_[this->i_];
194  }
195 
196 
197  // w_window<D,W>
198 
199  template <typename D, typename W>
200  inline
202  {
203  }
204 
205  template <typename D, typename W>
206  inline
207  const mln::window<D>&
208  w_window<D,W>::win() const
209  {
210  return win_;
211  }
212 
213  template <typename D, typename W>
214  inline
215  const std::vector<D>&
217  {
218  return win_.std_vector();
219  }
220 
221  template <typename D, typename W>
222  inline
223  const std::vector<W>&
224  w_window<D,W>::weights() const
225  {
226  return wei_;
227  }
228 
229  template <typename D, typename W>
230  inline
231  W
232  w_window<D,W>::w(unsigned i) const
233  {
234  mln_precondition(i < wei_.size());
235  mln_invariant(wei_.size() == win_.size());
236  return wei_[i];
237  }
238 
239  template <typename D, typename W>
240  inline
241  w_window<D,W>&
242  w_window<D,W>::insert(const W& w, const D& d)
243  {
244  mln_invariant(wei_.size() == win_.size());
245  mln_precondition(! win_.has(d));
246 
247  if (w == W(0)) // FIXME: Implicit restriction "W scalar"...
248  // no-op
249  return *this;
250 
251  // memorization: d_i -> w_i
252  std::map<D, W, util::ord<D> > memo_wei_;
253  for (unsigned i = 0; i < win_.size(); ++i)
254  memo_wei_[win_.dp(i)] = wei_[i];
255 
256  // insertion of d and w:
257  win_.insert(d);
258  memo_wei_[d] = w;
259 
260  // re-mapping: w_i <- d_i
261  wei_.resize(win_.size());
262  for (unsigned i = 0; i < win_.size(); ++i)
263  wei_[i] = memo_wei_[win_.dp(i)];
264 
265  mln_invariant(wei_.size() == win_.size());
266  return *this;
267  }
268 
269  template <typename D, typename W>
270  inline
271  bool
273  {
274  if (! win_.is_symmetric())
275  return false;
276  w_window<D,W> tmp;
277  tmp.sym();
278  return *this == tmp;
279  }
280 
281  template <typename D, typename W>
282  inline
283  void
285  {
286  w_window<D,W> tmp;
287  unsigned n = this->size();
288  for (unsigned i = 0; i < n; ++i)
289  tmp.insert(this->w(i), - this->dp(i));
290  *this = tmp;
291  }
292 
293  template <typename D, typename W>
294  inline
295  void
297  {
298  win_.clear();
299  wei_.clear();
300  }
301 
302 
303  // operators
304 
305  template <typename D, typename W>
306  inline
307  std::ostream& operator<<(std::ostream& ostr, const w_window<D,W>& w_win)
308  {
309  ostr << '[';
310  for (unsigned i = 0; i < w_win.win().size(); ++i)
311  ostr << w_win.dp(i) << ':' << w_win.w(i) << ' ';
312  return ostr << ']';
313  }
314 
315  template <typename D, typename Wl, typename Wr>
316  inline
317  bool operator==(const w_window<D,Wl>& lhs, const w_window<D,Wr>& rhs)
318  {
319  if (lhs.size() != rhs.size())
320  return false;
321  if (lhs.win() != rhs.win())
322  return false;
323  const std::vector<Wl>& wl = lhs.weights();
324  const std::vector<Wr>& wr = rhs.weights();
325  mln_assertion(wl.size() == wr.size());
326  for (unsigned i = 0; i < wl.size(); ++i)
327  if (wr[i] != wl[i])
328  return false;
329  return true;
330  }
331 
332 
333  // Conversions
334 
335  template <typename D, typename W, typename I>
336  void
337  from_to_(const w_window<D,W>& w_win, Image<I>& ima_)
338  {
339  typedef mln_site(I) P;
340  mlc_converts_to(D, mln_delta(P))::check();
341  mlc_converts_to(W, mln_value(I))::check();
342 
343  I& ima = exact(ima_);
344  mln_precondition(! ima.is_valid());
345  mln_precondition(w_win.is_valid());
346 
347  ima.init_(geom::bbox(w_win));
348  {
349  // data::fill(ima, literal::zero) is:
350  mln_value(I) zero = literal::zero;
351  mln_piter(I) p(ima.domain());
352  for_all(p)
353  ima(p) = zero;
354  }
355 
356  unsigned n = w_win.size();
357  for (unsigned i = 0; i < n; ++i)
358  ima(convert::to<P>(w_win.dp(i))) = w_win.w(i);
359  }
360 
361  template <typename V, unsigned S, typename D, typename W>
362  void
363  from_to_(const V (&weight)[S], w_window<D,W>& to)
364  {
365  mlc_bool(S != 0)::check();
366  mlc_converts_to(V, W)::check();
367  enum { d = D::dim,
368  s = mlc_root(d,S)::value / 2 };
369  metal::bool_<(mlc_pow_int(2 * s + 1, d) == S)>::check();
370  to.clear();
371  typedef mln_site(D) P;
372  box<P> b(all_to(-s), all_to(+s));
373  mln_fwd_piter(box<P>) p(b);
374  unsigned i = 0;
375  V zero = literal::zero;
376  for_all(p)
377  {
378  if (weight[i] != zero)
379  to.insert(weight[i], convert::to<D>(p));
380  ++i;
381  }
382 
383  }
384 
385 # endif // ! MLN_INCLUDE_ONLY
386 
387 } // end of namespace mln
388 
389 
390 # include <mln/make/w_window.hh>
391 
392 
393 #endif // ! MLN_CORE_W_WINDOW_HH