27 #ifndef SCRIBO_SUBSAMPLING_INTEGRAL_HH
28 # define SCRIBO_SUBSAMPLING_INTEGRAL_HH
34 #include <mln/core/concept/image.hh>
35 #include <mln/core/concept/box.hh>
36 #include <mln/make/box2d.hh>
37 #include <mln/metal/equal.hh>
38 #include <mln/extension/fill.hh>
39 #include <mln/debug/println.hh>
40 #include <mln/debug/println_with_border.hh>
64 template <
typename I,
typename J>
66 integral(const
Image<I>& input_,
unsigned scale,
67 Image<J>& integral_sum_sum_2,
68 const mln_domain(I)& output_domain,
unsigned border_thickness);
81 template <typename I, typename J>
84 integral(const
Image<I>& input_,
unsigned scale,
85 Image<J>& integral_sum_sum_2);
87 # ifndef MLN_INCLUDE_ONLY
95 template <
typename I,
typename J>
98 integral_3(const
Image<I>& input_,
99 Image<J>& integral_sum_sum_2_,
100 const mln_domain(I)& output_domain,
101 unsigned border_thickness)
103 mln_trace(
"subsampling::impl::integral_3");
105 const unsigned scale = 3;
107 const I& input =
exact(input_);
108 J& integral_sum_sum_2 =
exact(integral_sum_sum_2_);
110 mln_precondition(input.is_valid());
111 mln_precondition(input.domain().pmin() == literal::origin);
112 mln_precondition(scale > 1);
114 typedef mln_value(I) V;
115 typedef mln_sum(V) S;
116 typedef mln_value(J) V2;
117 typedef mln_site(I) P;
119 mln_concrete(I) sub(output_domain, border_thickness);
120 V* p_sub = sub.buffer();
122 integral_sum_sum_2.init_(output_domain, border_thickness);
123 V2* p_integ = integral_sum_sum_2.buffer();
125 const
int up = sub.delta_offset(
dpoint2d(-1, 0));
127 const
unsigned nrows = 3 * output_domain.
nrows();
128 const
unsigned ncols = 3 * output_domain.
ncols();
132 unsigned b_offset = sub.delta_offset(dpoint2d(border_thickness,
137 S h_sum = 0, h_sum_2 = 0;
138 const V* ptr1 = & input.at_(row, 0);
139 const V* ptr2 = & input.at_(row + 1, 0);
140 const V* ptr3 = & input.at_(row + 2, 0);
141 for (
unsigned col = 0; col <
ncols; col += scale)
143 V v11 = *ptr1, v12 = *(ptr1 + 1), v13 = *(ptr1 + 2),
144 v21 = *ptr2, v22 = *(ptr2 + 1), v23 = *(ptr2 + 2),
145 v31 = *ptr3, v32 = *(ptr3 + 1), v33 = *(ptr3 + 2);
149 S local_sum = v11 + v12 + v13
152 local_sum_2 = v11*v11 + v12*v12 + v13*v13
153 + v21*v21 + v22*v22 + v23*v23
154 + v31*v31 + v32*v32 + v33*v33;
158 h_sum_2 += local_sum_2;
161 p_integ->first() = h_sum;
162 p_integ->second() = h_sum_2;
168 unsigned b_next = 2 * border_thickness;
173 for (row += scale; row <
nrows; row += scale)
175 S h_sum = 0, h_sum_2 = 0;
176 const V* ptr1 = & input.at_(row, 0);
177 const V* ptr2 = & input.at_(row + 1, 0);
178 const V* ptr3 = & input.at_(row + 2, 0);
179 for (
unsigned col = 0; col <
ncols; col += scale)
181 V v11 = *ptr1, v12 = *(ptr1 + 1), v13 = *(ptr1 + 2),
182 v21 = *ptr2, v22 = *(ptr2 + 1), v23 = *(ptr2 + 2),
183 v31 = *ptr3, v32 = *(ptr3 + 1), v33 = *(ptr3 + 2);
187 S local_sum = v11 + v12 + v13
190 local_sum_2 = v11*v11 + v12*v12 + v13*v13
191 + v21*v21 + v22*v22 + v23*v23
192 + v31*v31 + v32*v32 + v33*v33;
196 h_sum_2 += local_sum_2;
198 p_integ->first() = h_sum + (p_integ +
up)->first();
199 p_integ->second() = h_sum_2 + (p_integ +
up)->second();
212 template <
typename I,
typename J>
215 integral_2(const
Image<I>& input_,
216 Image<J>& integral_sum_sum_2_,
217 const mln_domain(I)& output_domain,
218 unsigned border_thickness)
220 mln_trace(
"subsampling::impl::integral_2");
222 const unsigned scale = 2;
224 const I& input =
exact(input_);
225 J& integral_sum_sum_2 =
exact(integral_sum_sum_2_);
227 typedef mln_value(I) V;
228 typedef mln_sum(V) S;
229 typedef mln_site(I) P;
230 typedef mln_value(J) V2;
232 mlc_bool(P::dim == 2)::check();
233 mln_precondition(input.is_valid());
234 mln_precondition(input.domain().pmin() == literal::origin);
235 mln_precondition(scale > 1);
237 mln_concrete(I) sub(output_domain, border_thickness);
238 V* p_sub = sub.buffer();
240 integral_sum_sum_2.init_(output_domain, border_thickness);
241 V2* p_integ = integral_sum_sum_2.buffer();
243 const
int up = sub.delta_offset(dpoint2d(-1, 0));
245 const
unsigned nrows = 2 * output_domain.nrows();
246 const
unsigned ncols = 2 * output_domain.ncols();
248 extension::
fill(sub, 0);
250 unsigned b_offset = sub.delta_offset(dpoint2d(border_thickness,
257 S h_sum = 0, h_sum_2 = 0;
258 const V* ptr1 = & input.at_(row, 0);
259 const V* ptr2 = & input.at_(row + 1, 0);
260 for (
unsigned col = 0; col <
ncols; col += scale)
278 V v11 = *ptr1, v12 = *(ptr1 + 1),
279 v21 = *ptr2, v22 = *(ptr2 + 1);
282 S local_sum = v11 + v12 + v21 + v22,
283 local_sum_2 = v11*v11 + v12*v12 + v21*v21 + v22*v22;
286 h_sum_2 += local_sum_2;
292 p_integ->first() = h_sum;
293 p_integ->second() = h_sum_2;
299 unsigned b_next = 2 * border_thickness;
304 for (row += scale; row <
nrows; row += scale)
306 S h_sum = 0, h_sum_2 = 0;
307 const V* ptr1 = & input.at_(row, 0);
308 const V* ptr2 = & input.at_(row + 1, 0);
309 for (
unsigned col = 0; col <
ncols; col += scale)
313 V v11 = *ptr1, v12 = *(ptr1 + 1),
314 v21 = *ptr2, v22 = *(ptr2 + 1);
317 S local_sum = v11 + v12 + v21 + v22,
318 local_sum_2 = v11*v11 + v12*v12 + v21*v21 + v22*v22;
321 h_sum_2 += local_sum_2;
358 p_integ->first() = h_sum + (p_integ +
up)->first();
359 p_integ->second() = h_sum_2 + (p_integ +
up)->second();
372 template <
typename I,
typename J>
375 integral(const
Image<I>& input,
unsigned scale,
376 Image<J>& integral_sum_sum_2,
377 const mln_domain(I)& output_domain,
unsigned border_thickness)
382 return integral_3(input, integral_sum_sum_2,
383 output_domain, border_thickness);
385 return integral_2(input, integral_sum_sum_2,
386 output_domain, border_thickness);
388 std::cerr <<
"NYI!" << std::endl;
402 template <typename I, typename J>
405 integral(const
Image<I>& input_,
unsigned scale,
406 Image<J>& integral_sum_sum_2,
407 const mln_domain(I)& output_domain,
unsigned border_thickness)
409 mln_trace(
"subsampling::integral");
411 const I& input =
exact(input_);
413 mln_precondition(input.is_valid());
414 mln_precondition(input.domain().pmin() == literal::origin);
415 mln_precondition(scale > 1);
418 output = impl::integral(input, scale, integral_sum_sum_2,
419 output_domain, border_thickness);
424 template <typename I, typename J>
427 integral(const
Image<I>& input_,
unsigned scale,
428 Image<J>& integral_sum_sum_2)
430 mln_trace(
"subsampling::integral");
432 const I& input =
exact(input_);
434 mln_precondition(input.is_valid());
435 mln_precondition(input.domain().pmin() == literal::origin);
436 mln_precondition(scale > 1);
440 (input.ncols() + scale - 1) / scale);
442 output = integral(input_, scale, integral_sum_sum_2,
448 # endif // ! MLN_INCLUDE_ONLY
455 #endif // ! SCRIBO_SUBSAMPLING_INTEGRAL_HH