Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
linear/convolve.hh
1 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_LINEAR_CONVOLVE_HH
27 # define MLN_LINEAR_CONVOLVE_HH
28 
32 
33 # include <mln/core/concept/image.hh>
34 # include <mln/core/concept/weighted_window.hh>
35 # include <mln/linear/ch_convolve.hh>
36 # include <mln/accu/convolve.hh>
37 # include <mln/extension/adjust_duplicate.hh>
38 
39 
40 namespace mln
41 {
42 
43  namespace linear
44  {
45 
56  template <typename I, typename W>
57  mln_ch_convolve(I, W)
58  convolve(const Image<I>& input, const Weighted_Window<W>& w_win);
59 
60 
61 
62 # ifndef MLN_INCLUDE_ONLY
63 
64  // Tests.
65 
66  namespace internal
67  {
68 
69  template <typename I, typename W>
70  void
71  convolve_tests(const Image<I>& input,
72  const Weighted_Window<W>& w_win)
73  {
74  mln_precondition(exact(input).is_valid());
75  mln_precondition(exact(w_win).is_valid());
76  (void) input;
77  (void) w_win;
78  }
79 
80  } // end of namespace mln::linear::internal
81 
82 
83  // Implementation.
84 
85  namespace impl
86  {
87 
88  namespace generic
89  {
90 
91  template <typename I, typename W>
92  mln_ch_convolve(I, W)
93  convolve(const Image<I>& input_,
94  const Weighted_Window<W>& w_win_)
95  {
96  trace::entering("linear::impl::generic::convolve");
97 
98  const I& input = exact(input_);
99  const W& w_win = exact(w_win_);
100  internal::convolve_tests(input, w_win);
101 
102  extension::adjust_duplicate(input, w_win);
103 
104  typedef mln_ch_convolve(I, W) O;
105  O output;
106  initialize(output, input);
107 
108  accu::convolve<mln_value(I), mln_weight(W)> a;
109 
110  mln_piter(I) p(input.domain());
111  mln_qiter(W) q(w_win, p);
112 
113  for_all(p)
114  {
115  a.init();
116  for_all(q) if (input.has(q))
117  a.take(input(q), q.w());
118  output(p) = a.to_result();
119  }
120 
121  trace::exiting("linear::impl::generic::convolve");
122  return output;
123  }
124 
125  } // end of namespace mln::linear::impl::generic
126 
127 
128  template <typename I, typename W>
129  mln_ch_convolve(I, W)
130  convolve_fastest(const Image<I>& input_,
131  const Weighted_Window<W>& w_win_)
132  {
133  trace::entering("linear::impl::convolve_fastest");
134 
135  const I& input = exact(input_);
136  const W& w_win = exact(w_win_);
137  internal::convolve_tests(input, w_win);
138 
139  extension::adjust_duplicate(input, w_win);
140 
141  typedef mln_ch_convolve(I, W) O;
142  O output;
143  initialize(output, input);
144  mln_pixter(O) p_out(output);
145 
146  accu::convolve<mln_value(I), mln_weight(W)> a;
147 
148  mln_pixter(const I) p(input);
149  mln_qixter(const I, W) q(p, w_win);
150 
151  for_all_2(p, p_out)
152  {
153  a.init();
154  unsigned i = 0;
155  for_all(q)
156  a.take(q.val(), w_win.w(i++));
157  p_out.val() = a.to_result();
158  }
159 
160  trace::exiting("linear::impl::convolve_fastest");
161  return output;
162  }
163 
164  } // end of namespace mln::linear::impl
165 
166 
167  // Dispatch.
168 
169  namespace internal
170  {
171 
172  template <typename I, typename W>
173  mln_ch_convolve(I, W)
174  convolve_dispatch(trait::image::speed::any,
175  const Image<I>& input,
176  const Weighted_Window<W>& w_win)
177  {
178  return impl::generic::convolve(input, w_win);
179  }
180 
181  template <typename I, typename W>
182  mln_ch_convolve(I, W)
183  convolve_dispatch(trait::image::speed::fastest,
184  const Image<I>& input,
185  const Weighted_Window<W>& w_win)
186  {
187  return impl::convolve_fastest(input, w_win);
188  }
189 
190  template <typename I, typename W>
191  mln_ch_convolve(I, W)
192  convolve_dispatch(const Image<I>& input,
193  const Weighted_Window<W>& w_win)
194  {
195  return convolve_dispatch(mln_trait_image_speed(I)(),
196  input, w_win);
197  }
198 
199  } // end of namespace mln::linear::internal
200 
201 
202  // Facade.
203 
204  template <typename I, typename W>
205  mln_ch_convolve(I, W)
206  convolve(const Image<I>& input, const Weighted_Window<W>& w_win)
207  {
208  trace::entering("linear::convolve");
209 
210  internal::convolve_tests(input, w_win);
211 
212  mln_ch_convolve(I, W) output;
213  output = internal::convolve_dispatch(mln_trait_image_speed(I)(),
214  input, w_win);
215 
216  trace::exiting("linear::convolve");
217  return output;
218  }
219 
220 # endif // ! MLN_INCLUDE_ONLY
221 
222  } // end of namespace mln::linear
223 
224 } // end of namespace mln
225 
226 
227 #endif // ! MLN_LINEAR_CONVOLVE_HH