40 #ifndef PCL_INTEGRAL_IMAGE2D_IMPL_H_
41 #define PCL_INTEGRAL_IMAGE2D_IMPL_H_
46 template <
typename DataType,
unsigned Dimension>
void
49 compute_second_order_integral_images_ = compute_second_order_integral_images;
53 template <
typename DataType,
unsigned Dimension>
void
56 if ((width + 1) * (height + 1) > first_order_integral_image_.size () )
60 first_order_integral_image_.resize ( (width_ + 1) * (height_ + 1) );
61 finite_values_integral_image_.resize ( (width_ + 1) * (height_ + 1) );
62 if (compute_second_order_integral_images_)
63 second_order_integral_image_.resize ( (width_ + 1) * (height_ + 1) );
65 computeIntegralImages (data, row_stride, element_stride);
71 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
73 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
74 const unsigned upper_right_idx = upper_left_idx + width;
75 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
76 const unsigned lower_right_idx = lower_left_idx + width;
78 return (first_order_integral_image_[lower_right_idx] + first_order_integral_image_[upper_left_idx] -
79 first_order_integral_image_[upper_right_idx] - first_order_integral_image_[lower_left_idx] );
85 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
87 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
88 const unsigned upper_right_idx = upper_left_idx + width;
89 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
90 const unsigned lower_right_idx = lower_left_idx + width;
92 return (second_order_integral_image_[lower_right_idx] + second_order_integral_image_[upper_left_idx] -
93 second_order_integral_image_[upper_right_idx] - second_order_integral_image_[lower_left_idx] );
97 template <
typename DataType,
unsigned Dimension>
unsigned
99 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
101 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
102 const unsigned upper_right_idx = upper_left_idx + width;
103 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
104 const unsigned lower_right_idx = lower_left_idx + width;
106 return (finite_values_integral_image_[lower_right_idx] + finite_values_integral_image_[upper_left_idx] -
107 finite_values_integral_image_[upper_right_idx] - finite_values_integral_image_[lower_left_idx] );
113 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
115 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
116 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
117 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
118 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
120 return (first_order_integral_image_[lower_right_idx] + first_order_integral_image_[upper_left_idx] -
121 first_order_integral_image_[upper_right_idx] - first_order_integral_image_[lower_left_idx] );
127 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
129 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
130 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
131 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
132 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
134 return (second_order_integral_image_[lower_right_idx] + second_order_integral_image_[upper_left_idx] -
135 second_order_integral_image_[upper_right_idx] - second_order_integral_image_[lower_left_idx] );
139 template <
typename DataType,
unsigned Dimension>
unsigned
141 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
143 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
144 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
145 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
146 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
148 return (finite_values_integral_image_[lower_right_idx] + finite_values_integral_image_[upper_left_idx] -
149 finite_values_integral_image_[upper_right_idx] - finite_values_integral_image_[lower_left_idx] );
153 template <
typename DataType,
unsigned Dimension>
void
155 const DataType *data,
unsigned row_stride,
unsigned element_stride)
157 ElementType* previous_row = &first_order_integral_image_[0];
158 ElementType* current_row = previous_row + (width_ + 1);
159 memset (previous_row, 0,
sizeof (ElementType) * (width_ + 1));
161 unsigned* count_previous_row = &finite_values_integral_image_[0];
162 unsigned* count_current_row = count_previous_row + (width_ + 1);
163 memset (count_previous_row, 0,
sizeof (
unsigned) * (width_ + 1));
165 if (!compute_second_order_integral_images_)
167 for (
unsigned rowIdx = 0; rowIdx < height_; ++rowIdx, data += row_stride,
168 previous_row = current_row, current_row += (width_ + 1),
169 count_previous_row = count_current_row, count_current_row += (width_ + 1))
171 current_row [0].setZero ();
172 count_current_row [0] = 0;
173 for (
unsigned colIdx = 0, valIdx = 0; colIdx < width_; ++colIdx, valIdx += element_stride)
175 current_row [colIdx + 1] = previous_row [colIdx + 1] + current_row [colIdx] - previous_row [colIdx];
176 count_current_row [colIdx + 1] = count_previous_row [colIdx + 1] + count_current_row [colIdx] - count_previous_row [colIdx];
177 const InputType* element = reinterpret_cast <
const InputType*> (&data [valIdx]);
178 if (pcl_isfinite (element->sum ()))
180 current_row [colIdx + 1] += element->template cast<typename IntegralImageTypeTraits<DataType>::IntegralType>();
181 ++(count_current_row [colIdx + 1]);
188 SecondOrderType* so_previous_row = &second_order_integral_image_[0];
189 SecondOrderType* so_current_row = so_previous_row + (width_ + 1);
190 memset (so_previous_row, 0,
sizeof (SecondOrderType) * (width_ + 1));
192 SecondOrderType so_element;
193 for (
unsigned rowIdx = 0; rowIdx < height_; ++rowIdx, data += row_stride,
194 previous_row = current_row, current_row += (width_ + 1),
195 count_previous_row = count_current_row, count_current_row += (width_ + 1),
196 so_previous_row = so_current_row, so_current_row += (width_ + 1))
198 current_row [0].setZero ();
199 so_current_row [0].setZero ();
200 count_current_row [0] = 0;
201 for (
unsigned colIdx = 0, valIdx = 0; colIdx < width_; ++colIdx, valIdx += element_stride)
203 current_row [colIdx + 1] = previous_row [colIdx + 1] + current_row [colIdx] - previous_row [colIdx];
204 so_current_row [colIdx + 1] = so_previous_row [colIdx + 1] + so_current_row [colIdx] - so_previous_row [colIdx];
205 count_current_row [colIdx + 1] = count_previous_row [colIdx + 1] + count_current_row [colIdx] - count_previous_row [colIdx];
207 const InputType* element = reinterpret_cast <
const InputType*> (&data [valIdx]);
208 if (pcl_isfinite (element->sum ()))
210 current_row [colIdx + 1] += element->template cast<typename IntegralImageTypeTraits<DataType>::IntegralType>();
211 ++(count_current_row [colIdx + 1]);
212 for (
unsigned myIdx = 0, elIdx = 0; myIdx < Dimension; ++myIdx)
213 for (
unsigned mxIdx = myIdx; mxIdx < Dimension; ++mxIdx, ++elIdx)
214 so_current_row [colIdx + 1][elIdx] += (*element)[myIdx] * (*element)[mxIdx];
223 template <
typename DataType>
void
226 if ((width + 1) * (height + 1) > first_order_integral_image_.size () )
230 first_order_integral_image_.resize ( (width_ + 1) * (height_ + 1) );
231 finite_values_integral_image_.resize ( (width_ + 1) * (height_ + 1) );
232 if (compute_second_order_integral_images_)
233 second_order_integral_image_.resize ( (width_ + 1) * (height_ + 1) );
235 computeIntegralImages (data, row_stride, element_stride);
241 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
243 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
244 const unsigned upper_right_idx = upper_left_idx + width;
245 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
246 const unsigned lower_right_idx = lower_left_idx + width;
248 return (first_order_integral_image_[lower_right_idx] + first_order_integral_image_[upper_left_idx] -
249 first_order_integral_image_[upper_right_idx] - first_order_integral_image_[lower_left_idx] );
255 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
257 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
258 const unsigned upper_right_idx = upper_left_idx + width;
259 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
260 const unsigned lower_right_idx = lower_left_idx + width;
262 return (second_order_integral_image_[lower_right_idx] + second_order_integral_image_[upper_left_idx] -
263 second_order_integral_image_[upper_right_idx] - second_order_integral_image_[lower_left_idx] );
267 template <
typename DataType>
unsigned
269 unsigned start_x,
unsigned start_y,
unsigned width,
unsigned height)
const
271 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
272 const unsigned upper_right_idx = upper_left_idx + width;
273 const unsigned lower_left_idx = (start_y + height) * (width_ + 1) + start_x;
274 const unsigned lower_right_idx = lower_left_idx + width;
276 return (finite_values_integral_image_[lower_right_idx] + finite_values_integral_image_[upper_left_idx] -
277 finite_values_integral_image_[upper_right_idx] - finite_values_integral_image_[lower_left_idx] );
283 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
285 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
286 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
287 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
288 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
290 return (first_order_integral_image_[lower_right_idx] + first_order_integral_image_[upper_left_idx] -
291 first_order_integral_image_[upper_right_idx] - first_order_integral_image_[lower_left_idx] );
297 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
299 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
300 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
301 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
302 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
304 return (second_order_integral_image_[lower_right_idx] + second_order_integral_image_[upper_left_idx] -
305 second_order_integral_image_[upper_right_idx] - second_order_integral_image_[lower_left_idx] );
309 template <
typename DataType>
unsigned
311 unsigned start_x,
unsigned start_y,
unsigned end_x,
unsigned end_y)
const
313 const unsigned upper_left_idx = start_y * (width_ + 1) + start_x;
314 const unsigned upper_right_idx = start_y * (width_ + 1) + end_x;
315 const unsigned lower_left_idx = end_y * (width_ + 1) + start_x;
316 const unsigned lower_right_idx = end_y * (width_ + 1) + end_x;
318 return (finite_values_integral_image_[lower_right_idx] + finite_values_integral_image_[upper_left_idx] -
319 finite_values_integral_image_[upper_right_idx] - finite_values_integral_image_[lower_left_idx] );
323 template <
typename DataType>
void
325 const DataType *data,
unsigned row_stride,
unsigned element_stride)
327 ElementType* previous_row = &first_order_integral_image_[0];
328 ElementType* current_row = previous_row + (width_ + 1);
329 memset (previous_row, 0,
sizeof (ElementType) * (width_ + 1));
331 unsigned* count_previous_row = &finite_values_integral_image_[0];
332 unsigned* count_current_row = count_previous_row + (width_ + 1);
333 memset (count_previous_row, 0,
sizeof (
unsigned) * (width_ + 1));
335 if (!compute_second_order_integral_images_)
337 for (
unsigned rowIdx = 0; rowIdx < height_; ++rowIdx, data += row_stride,
338 previous_row = current_row, current_row += (width_ + 1),
339 count_previous_row = count_current_row, count_current_row += (width_ + 1))
341 current_row [0] = 0.0;
342 count_current_row [0] = 0;
343 for (
unsigned colIdx = 0, valIdx = 0; colIdx < width_; ++colIdx, valIdx += element_stride)
345 current_row [colIdx + 1] = previous_row [colIdx + 1] + current_row [colIdx] - previous_row [colIdx];
346 count_current_row [colIdx + 1] = count_previous_row [colIdx + 1] + count_current_row [colIdx] - count_previous_row [colIdx];
347 if (pcl_isfinite (data [valIdx]))
349 current_row [colIdx + 1] += data [valIdx];
350 ++(count_current_row [colIdx + 1]);
357 SecondOrderType* so_previous_row = &second_order_integral_image_[0];
358 SecondOrderType* so_current_row = so_previous_row + (width_ + 1);
359 memset (so_previous_row, 0,
sizeof (SecondOrderType) * (width_ + 1));
361 for (
unsigned rowIdx = 0; rowIdx < height_; ++rowIdx, data += row_stride,
362 previous_row = current_row, current_row += (width_ + 1),
363 count_previous_row = count_current_row, count_current_row += (width_ + 1),
364 so_previous_row = so_current_row, so_current_row += (width_ + 1))
366 current_row [0] = 0.0;
367 so_current_row [0] = 0.0;
368 count_current_row [0] = 0;
369 for (
unsigned colIdx = 0, valIdx = 0; colIdx < width_; ++colIdx, valIdx += element_stride)
371 current_row [colIdx + 1] = previous_row [colIdx + 1] + current_row [colIdx] - previous_row [colIdx];
372 so_current_row [colIdx + 1] = so_previous_row [colIdx + 1] + so_current_row [colIdx] - so_previous_row [colIdx];
373 count_current_row [colIdx + 1] = count_previous_row [colIdx + 1] + count_current_row [colIdx] - count_previous_row [colIdx];
374 if (pcl_isfinite (data[valIdx]))
376 current_row [colIdx + 1] += data[valIdx];
377 so_current_row [colIdx + 1] += data[valIdx] * data[valIdx];
378 ++(count_current_row [colIdx + 1]);
384 #endif // PCL_INTEGRAL_IMAGE2D_IMPL_H_
Determines an integral image representation for a given organized data array.
unsigned getFiniteElementsCount(unsigned start_x, unsigned start_y, unsigned width, unsigned height) const
Compute the number of finite elements within a given rectangle.
void setSecondOrderComputation(bool compute_second_order_integral_images)
sets the computation for second order integral images on or off.
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.
ElementType getFirstOrderSumSE(unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const
Compute the first order sum within a given rectangle.
Eigen::Matrix< typename IntegralImageTypeTraits< DataType >::IntegralType, second_order_size, 1 > SecondOrderType
SecondOrderType getSecondOrderSumSE(unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const
Compute the second 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.
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.
Eigen::Matrix< typename IntegralImageTypeTraits< DataType >::IntegralType, Dimension, 1 > ElementType