41 #ifndef PCL_INTEGRAL_IMAGE2D_IMPL_H_
42 #define PCL_INTEGRAL_IMAGE2D_IMPL_H_
48 template <
typename DataType,
unsigned Dimension>
void
51 compute_second_order_integral_images_ = compute_second_order_integral_images;
55 template <
typename DataType,
unsigned Dimension>
void
58 if ((width + 1) * (height + 1) > first_order_integral_image_.size () )
62 const std::size_t ii_size =
static_cast<std::size_t
>(width_ + 1) *
static_cast<std::size_t
>(height_ + 1);
63 first_order_integral_image_.resize (ii_size);
64 finite_values_integral_image_.resize (ii_size);
65 if (compute_second_order_integral_images_)
66 second_order_integral_image_.resize (ii_size);
68 computeIntegralImages (data, row_stride, element_stride);
74 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
76 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
77 const unsigned upper_right_idx = upper_left_idx + width;
78 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
79 const unsigned lower_right_idx = lower_left_idx + width;
81 return (first_order_integral_image_[lower_right_idx] + first_order_integral_image_[upper_left_idx] -
82 first_order_integral_image_[upper_right_idx] - first_order_integral_image_[lower_left_idx] );
88 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
90 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
91 const unsigned upper_right_idx = upper_left_idx + width;
92 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
93 const unsigned lower_right_idx = lower_left_idx + width;
95 return (second_order_integral_image_[lower_right_idx] + second_order_integral_image_[upper_left_idx] -
96 second_order_integral_image_[upper_right_idx] - second_order_integral_image_[lower_left_idx] );
100 template <
typename DataType,
unsigned Dimension>
unsigned
102 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
104 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
105 const unsigned upper_right_idx = upper_left_idx + width;
106 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
107 const unsigned lower_right_idx = lower_left_idx + width;
109 return (finite_values_integral_image_[lower_right_idx] + finite_values_integral_image_[upper_left_idx] -
110 finite_values_integral_image_[upper_right_idx] - finite_values_integral_image_[lower_left_idx] );
116 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
118 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
119 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
120 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
121 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
123 return (first_order_integral_image_[lower_right_idx] + first_order_integral_image_[upper_left_idx] -
124 first_order_integral_image_[upper_right_idx] - first_order_integral_image_[lower_left_idx] );
130 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
132 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
133 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
134 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
135 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
137 return (second_order_integral_image_[lower_right_idx] + second_order_integral_image_[upper_left_idx] -
138 second_order_integral_image_[upper_right_idx] - second_order_integral_image_[lower_left_idx] );
142 template <
typename DataType,
unsigned Dimension>
unsigned
144 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
146 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
147 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
148 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
149 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
151 return (finite_values_integral_image_[lower_right_idx] + finite_values_integral_image_[upper_left_idx] -
152 finite_values_integral_image_[upper_right_idx] - finite_values_integral_image_[lower_left_idx] );
156 template <
typename DataType,
unsigned Dimension>
void
158 const DataType *data,
unsigned row_stride,
unsigned element_stride)
160 ElementType* previous_row = first_order_integral_image_.data();
161 ElementType* current_row = previous_row + (width_ + 1);
162 for (
unsigned int i = 0; i < (width_ + 1); ++i)
163 previous_row[i].setZero();
165 unsigned* count_previous_row = finite_values_integral_image_.data();
166 unsigned* count_current_row = count_previous_row + (width_ + 1);
167 std::fill_n(count_previous_row, width_ + 1, 0);
169 if (!compute_second_order_integral_images_)
171 for (
unsigned rowIdx = 0; rowIdx < height_; ++rowIdx, data += row_stride,
172 previous_row = current_row, current_row += (width_ + 1),
173 count_previous_row = count_current_row, count_current_row += (width_ + 1))
175 current_row [0].setZero ();
176 count_current_row [0] = 0;
177 for (
unsigned colIdx = 0, valIdx = 0; colIdx < width_; ++colIdx, valIdx += element_stride)
179 current_row [colIdx + 1] = previous_row [colIdx + 1] + current_row [colIdx] - previous_row [colIdx];
180 count_current_row [colIdx + 1] = count_previous_row [colIdx + 1] + count_current_row [colIdx] - count_previous_row [colIdx];
181 const auto* element =
reinterpret_cast <const InputType*
> (&data [valIdx]);
182 if (std::isfinite (element->sum ()))
184 current_row [colIdx + 1] += element->template cast<typename IntegralImageTypeTraits<DataType>::IntegralType>();
185 ++(count_current_row [colIdx + 1]);
192 SecondOrderType* so_previous_row = second_order_integral_image_.data();
194 for (
unsigned int i = 0; i < (width_ + 1); ++i)
195 so_previous_row[i].setZero();
197 for (
unsigned rowIdx = 0; rowIdx < height_; ++rowIdx, data += row_stride,
198 previous_row = current_row, current_row += (width_ + 1),
199 count_previous_row = count_current_row, count_current_row += (width_ + 1),
200 so_previous_row = so_current_row, so_current_row += (width_ + 1))
202 current_row [0].setZero ();
203 so_current_row [0].setZero ();
204 count_current_row [0] = 0;
205 for (
unsigned colIdx = 0, valIdx = 0; colIdx < width_; ++colIdx, valIdx += element_stride)
207 current_row [colIdx + 1] = previous_row [colIdx + 1] + current_row [colIdx] - previous_row [colIdx];
208 so_current_row [colIdx + 1] = so_previous_row [colIdx + 1] + so_current_row [colIdx] - so_previous_row [colIdx];
209 count_current_row [colIdx + 1] = count_previous_row [colIdx + 1] + count_current_row [colIdx] - count_previous_row [colIdx];
211 const auto* element =
reinterpret_cast <const InputType*
> (&data [valIdx]);
212 if (std::isfinite (element->sum ()))
214 current_row [colIdx + 1] += element->template cast<typename IntegralImageTypeTraits<DataType>::IntegralType>();
215 ++(count_current_row [colIdx + 1]);
216 for (
unsigned myIdx = 0, elIdx = 0; myIdx < Dimension; ++myIdx)
217 for (
unsigned mxIdx = myIdx; mxIdx < Dimension; ++mxIdx, ++elIdx)
218 so_current_row [colIdx + 1][elIdx] += (*element)[myIdx] * (*element)[mxIdx];
226 template <
typename DataType>
void
229 if ((width + 1) * (height + 1) > first_order_integral_image_.size () )
233 const std::size_t ii_size =
static_cast<std::size_t
>(width_ + 1) *
static_cast<std::size_t
>(height_ + 1);
234 first_order_integral_image_.resize (ii_size);
235 finite_values_integral_image_.resize (ii_size);
236 if (compute_second_order_integral_images_)
237 second_order_integral_image_.resize (ii_size);
239 computeIntegralImages (data, row_stride, element_stride);
245 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
247 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
248 const unsigned upper_right_idx = upper_left_idx + width;
249 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
250 const unsigned lower_right_idx = lower_left_idx + width;
252 return (first_order_integral_image_[lower_right_idx] + first_order_integral_image_[upper_left_idx] -
253 first_order_integral_image_[upper_right_idx] - first_order_integral_image_[lower_left_idx] );
259 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
261 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
262 const unsigned upper_right_idx = upper_left_idx + width;
263 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
264 const unsigned lower_right_idx = lower_left_idx + width;
266 return (second_order_integral_image_[lower_right_idx] + second_order_integral_image_[upper_left_idx] -
267 second_order_integral_image_[upper_right_idx] - second_order_integral_image_[lower_left_idx] );
271 template <
typename DataType>
unsigned
273 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
275 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
276 const unsigned upper_right_idx = upper_left_idx + width;
277 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
278 const unsigned lower_right_idx = lower_left_idx + width;
280 return (finite_values_integral_image_[lower_right_idx] + finite_values_integral_image_[upper_left_idx] -
281 finite_values_integral_image_[upper_right_idx] - finite_values_integral_image_[lower_left_idx] );
287 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
289 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
290 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
291 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
292 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
294 return (first_order_integral_image_[lower_right_idx] + first_order_integral_image_[upper_left_idx] -
295 first_order_integral_image_[upper_right_idx] - first_order_integral_image_[lower_left_idx] );
301 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
303 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
304 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
305 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
306 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
308 return (second_order_integral_image_[lower_right_idx] + second_order_integral_image_[upper_left_idx] -
309 second_order_integral_image_[upper_right_idx] - second_order_integral_image_[lower_left_idx] );
313 template <
typename DataType>
unsigned
315 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
317 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
318 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
319 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
320 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
322 return (finite_values_integral_image_[lower_right_idx] + finite_values_integral_image_[upper_left_idx] -
323 finite_values_integral_image_[upper_right_idx] - finite_values_integral_image_[lower_left_idx] );
327 template <
typename DataType>
void
329 const DataType *data,
unsigned row_stride,
unsigned element_stride)
331 ElementType* previous_row = first_order_integral_image_.data();
332 ElementType* current_row = previous_row + (width_ + 1);
333 std::fill_n(previous_row, width_ + 1, 0);
335 unsigned* count_previous_row = finite_values_integral_image_.data();
336 unsigned* count_current_row = count_previous_row + (width_ + 1);
337 std::fill_n(count_previous_row, width_ + 1, 0);
339 if (!compute_second_order_integral_images_)
341 for (
unsigned rowIdx = 0; rowIdx < height_; ++rowIdx, data += row_stride,
342 previous_row = current_row, current_row += (width_ + 1),
343 count_previous_row = count_current_row, count_current_row += (width_ + 1))
345 current_row [0] = 0.0;
346 count_current_row [0] = 0;
347 for (
unsigned colIdx = 0, valIdx = 0; colIdx < width_; ++colIdx, valIdx += element_stride)
349 current_row [colIdx + 1] = previous_row [colIdx + 1] + current_row [colIdx] - previous_row [colIdx];
350 count_current_row [colIdx + 1] = count_previous_row [colIdx + 1] + count_current_row [colIdx] - count_previous_row [colIdx];
351 if (std::isfinite (data [valIdx]))
353 current_row [colIdx + 1] += data [valIdx];
354 ++(count_current_row [colIdx + 1]);
361 SecondOrderType* so_previous_row = second_order_integral_image_.data();
363 std::fill_n(so_previous_row, width_ + 1, 0);
365 for (
unsigned rowIdx = 0; rowIdx < height_; ++rowIdx, data += row_stride,
366 previous_row = current_row, current_row += (width_ + 1),
367 count_previous_row = count_current_row, count_current_row += (width_ + 1),
368 so_previous_row = so_current_row, so_current_row += (width_ + 1))
370 current_row [0] = 0.0;
371 so_current_row [0] = 0.0;
372 count_current_row [0] = 0;
373 for (
unsigned colIdx = 0, valIdx = 0; colIdx < width_; ++colIdx, valIdx += element_stride)
375 current_row [colIdx + 1] = previous_row [colIdx + 1] + current_row [colIdx] - previous_row [colIdx];
376 so_current_row [colIdx + 1] = so_previous_row [colIdx + 1] + so_current_row [colIdx] - so_previous_row [colIdx];
377 count_current_row [colIdx + 1] = count_previous_row [colIdx + 1] + count_current_row [colIdx] - count_previous_row [colIdx];
378 if (std::isfinite (data[valIdx]))
380 current_row [colIdx + 1] += data[valIdx];
381 so_current_row [colIdx + 1] += data[valIdx] * data[valIdx];
382 ++(count_current_row [colIdx + 1]);
Determines an integral image representation for a given organized data array.
void setSecondOrderComputation(bool compute_second_order_integral_images)
sets the computation for second order integral images on or off.
Eigen::Matrix< typename IntegralImageTypeTraits< DataType >::IntegralType, Dimension, 1 > ElementType
ElementType getFirstOrderSumSE(unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const
Compute the first order sum within a given rectangle.
ElementType getFirstOrderSum(unsigned start_x, unsigned start_y, unsigned width, unsigned height) const
Compute the first order sum within a given rectangle.
unsigned getFiniteElementsCount(unsigned start_x, unsigned start_y, unsigned width, unsigned height) const
Compute the number of finite elements within a given rectangle.
Eigen::Matrix< typename IntegralImageTypeTraits< DataType >::IntegralType, second_order_size, 1 > SecondOrderType
void setInput(const DataType *data, unsigned width, unsigned height, unsigned element_stride, unsigned row_stride)
Set the input data to compute the integral image for.
SecondOrderType getSecondOrderSumSE(unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const
Compute the second order sum within a given rectangle.
SecondOrderType getSecondOrderSum(unsigned start_x, unsigned start_y, unsigned width, unsigned height) const
Compute the second order sum within a given rectangle.
unsigned getFiniteElementsCountSE(unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const
Compute the number of finite elements within a given rectangle.