$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
init_integral_image.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_UTIL_INIT_INTEGRAL_IMAGE_HH
28 # define SCRIBO_UTIL_INIT_INTEGRAL_IMAGE_HH
29 
33 
34 # include <mln/core/image/image2d.hh>
35 
36 namespace scribo
37 {
38 
39  namespace util
40  {
41 
42  using namespace mln;
43 
44 
45  template <typename I, typename F>
46  mln_ch_value(I, mln_result(F))
47  init_integral_image(const Image<I>& input, unsigned scale, F& func);
48 
49  template <typename I, typename F>
50  mln_ch_value(I, mln_result(F))
51  init_integral_image(const Image<I>& input, unsigned scale, F& func,
52  unsigned border);
53 
54 
55 # ifndef MLN_INCLUDE_ONLY
56 
57  namespace impl
58  {
59 
60  namespace generic
61  {
62 
63  template <typename I, typename F>
64  mln_ch_value(I, mln_result(F))
65  init_integral_image(const Image<I>& /* input */, unsigned /* scale */,
66  F& /* f */, const mln_box(I)& /* output_domain */,
67  unsigned /* border */)
68  {
69  mln_trace("scribo::util::impl::generic::init_integral_image");
70  typedef mln_ch_value(I, mln_result(F)) J;
71 
72  // Not implemented
73  mlc_abort(I)::check();
74 
75  return J();
76  }
77 
78  } // end of namespace scribo::util::impl::generic
79 
80 
81  template <typename I, typename F>
82  mln_ch_value(I, mln_result(F))
83  init_integral_image_fastest(const Image<I>& input_, unsigned scale, F& f,
84  const mln_box(I)& output_domain, unsigned border)
85  {
86  mln_trace("scribo::util::impl::init_integral_image_fastest");
87 
88  const I& input = exact(input_);
89  typedef mln_ch_value(I, mln_result(F)) J;
90 
91  mln_precondition(input.is_valid());
92  mln_precondition(input.domain().pmin() == literal::origin);
93 
94  typedef mln_value(I) V;
95  typedef mln_sum(V) S;
96  typedef mln_value(J) V2;
97  typedef mln_site(I) P;
98 
99  J integral_sum_sum_2(output_domain, border);
100  V2* p_integ = integral_sum_sum_2.buffer();
101 
102  const int up = integral_sum_sum_2.delta_offset(dpoint2d(-1, 0));
103 
104  const unsigned nrows = scale * integral_sum_sum_2.nrows();
105  const unsigned ncols = scale * integral_sum_sum_2.ncols();
106 
107  unsigned row = 0;
108 
109  unsigned b_offset = integral_sum_sum_2.delta_offset(dpoint2d(border,
110  border));
111 
112  // First row (special case)
113  p_integ += b_offset;
114  {
115  f.begin_of_first_row(); // <---- begin_of_first_row()
116 
117  mln::util::array<const V*> ptr(scale);
118  for (unsigned s = 0; s < scale; ++s)
119  ptr[s] = & input.at_(row + s, 0);
120 
121  for (unsigned col = 0; col < ncols; col += scale)
122  {
123  f.begin_of_col(); // <---- begin_of_col()
124 
125  for (unsigned s = 0; s < scale; ++s)
126  for (unsigned i = 0; i < scale; ++i)
127  f.take(*(ptr[s]++)); // <---- take()
128 
129  // exception
130  *p_integ = f.to_result_first_row(); // <---- to_result_first_row()
131 
132  f.end_of_col(); // <---- end_of_col()
133  ++p_integ;
134  }
135  f.end_of_row(); // <---- end_of_row()
136  }
137 
138  unsigned b_next = 2 * border;
139 
140  // Other rows (general case)
141  p_integ += b_next;
142  for (row += scale; row < nrows; row += scale)
143  {
144  f.begin_of_row(); // <---- begin_of_row()
145 
146  mln::util::array<const V*> ptr(scale);
147  for (unsigned s = 0; s < scale; ++s)
148  ptr[s] = & input.at_(row + s, 0);
149 
150  for (unsigned col = 0; col < ncols; col += scale)
151  {
152  f.begin_of_col(); // <---- begin_of_col()
153 
154  for (unsigned s = 0; s < scale; ++s)
155  for (unsigned i = 0; i < scale; ++i)
156  f.take(*(ptr[s]++)); // <---- take()
157 
158  *p_integ = f.to_result(*(p_integ + up)); // <---- to_result()
159 
160  f.end_of_col(); // <---- end_of_col()
161  ++p_integ;
162  }
163  f.end_of_row(); // <---- end_of_row()
164  p_integ += b_next;
165  }
166 
167  return integral_sum_sum_2;
168  }
169 
170  } // end of namespace scribo::util::impl
171 
172 
173  // Dispatch
174 
175  namespace internal
176  {
177 
178  template <typename I, typename F>
179  mln_ch_value(I,mln_result(F))
180  init_integral_image_dispatch(mln::trait::image::speed::fastest,
181  const Image<I>& input, unsigned scale,
182  F& func, const mln_box(I)& output_domain,
183  unsigned border)
184  {
185  return impl::init_integral_image_fastest(input, scale, func,
186  output_domain, border);
187  }
188 
189 
190  template <typename I, typename F>
191  mln_ch_value(I,mln_result(F))
192  init_integral_image_dispatch(mln::trait::image::speed::any,
193  const Image<I>& input, unsigned scale,
194  F& func, const mln_box(I)& output_domain,
195  unsigned border)
196  {
197  return impl::generic::init_integral_image(input, scale, func,
198  output_domain, border);
199  }
200 
201 
202  template <typename I, typename F>
203  mln_ch_value(I,mln_result(F))
204  init_integral_image_dispatch(const Image<I>& input, unsigned scale, F& func,
205  const mln_box(I)& output_domain, unsigned border)
206  {
207  return init_integral_image_dispatch(mln_trait_image_speed(I)(),
208  input, scale, func, output_domain, border);
209  }
210 
211  } // end of namespace scribo::util::internal
212 
213 
214  // Facade
215 
216  template <typename I, typename F>
217  mln_ch_value(I,mln_result(F))
218  init_integral_image(const Image<I>& input_, unsigned scale, F& func,
219  const mln_box(I)& output_domain, unsigned border)
220  {
221  mln_trace("scribo::util::init_integral_image");
222 
223  const I& input = exact(input_);
224  mln_precondition(input.is_valid());
225  mln_precondition(input.domain().pmin() == literal::origin);
226 
227  mln_ch_value(I,mln_result(F))
228  output = internal::init_integral_image_dispatch(input, scale, func,
229  output_domain, border);
230 
231  return output;
232  }
233 
234  template <typename I, typename F>
235  mln_ch_value(I,mln_result(F))
236  init_integral_image(const Image<I>& input_, unsigned scale, F& func)
237  {
238  mln_trace("scribo::util::init_integral_image");
239 
240  const I& input = exact(input_);
241  mln_precondition(input.is_valid());
242  mln_precondition(input.domain().pmin() == literal::origin);
243 
245  output_domain = mln::make::box2d((input.nrows() + scale - 1) / scale,
246  (input.ncols() + scale - 1) / scale);
247 
248  mln_ch_value(I,mln_result(F))
249  output = init_integral_image(input, scale, func,
250  output_domain, exact(input).border());
251 
252  return output;
253  }
254 
255 #endif // ! MLN_INCLUDE_ONLY
256 
257  } // end of namespace scribo::util
258 
259 } // end of namespace scribo
260 
261 #endif // ! SCRIBO_UTIL_INIT_INTEGRAL_IMAGE_HH