Point Cloud Library (PCL)  1.14.0-dev
integral_image2D.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, Willow Garage, Inc.
6  * Copyright (c) 2012-, Open Perception, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of the copyright holder(s) nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * $Id: feature.h 2784 2011-10-15 22:05:38Z aichim $
38  */
39 
40 #pragma once
41 
42 #include <pcl/memory.h>
43 
44 #include <vector>
45 
46 
47 namespace pcl
48 {
49  template <typename DataType>
51  {
52  using Type = DataType;
53  using IntegralType = DataType;
54  };
55 
56  template <>
58  {
59  using Type = float;
60  using IntegralType = double;
61  };
62 
63  template <>
65  {
66  using Type = char;
67  using IntegralType = int;
68  };
69 
70  template <>
72  {
73  using Type = short;
74  using IntegralType = long;
75  };
76 
77  template <>
78  struct IntegralImageTypeTraits<unsigned short>
79  {
80  using Type = unsigned short;
81  using IntegralType = unsigned long;
82  };
83 
84  template <>
85  struct IntegralImageTypeTraits<unsigned char>
86  {
87  using Type = unsigned char;
88  using IntegralType = unsigned int;
89  };
90 
91  template <>
93  {
94  using Type = int;
95  using IntegralType = long;
96  };
97 
98  template <>
99  struct IntegralImageTypeTraits<unsigned int>
100  {
101  using Type = unsigned int;
102  using IntegralType = unsigned long;
103  };
104 
105  /** \brief Determines an integral image representation for a given organized data array
106  * \author Suat Gedikli
107  */
108  template <class DataType, unsigned Dimension>
110  {
111  public:
112  using Ptr = shared_ptr<IntegralImage2D<DataType, Dimension>>;
113  using ConstPtr = shared_ptr<const IntegralImage2D<DataType, Dimension>>;
114  static const unsigned second_order_size = (Dimension * (Dimension + 1)) >> 1;
115  using ElementType = Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::IntegralType, Dimension, 1>;
116  using SecondOrderType = Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::IntegralType, second_order_size, 1>;
117 
118  /** \brief Constructor for an Integral Image
119  * \param[in] compute_second_order_integral_images set to true if we want to compute a second order image
120  */
121  IntegralImage2D (bool compute_second_order_integral_images) :
122  first_order_integral_image_ (),
123  second_order_integral_image_ (),
124 
125  compute_second_order_integral_images_ (compute_second_order_integral_images)
126  {
127  }
128 
129  /** \brief Destructor */
130  virtual
131  ~IntegralImage2D () = default;
132 
133  /** \brief sets the computation for second order integral images on or off.
134  * \param compute_second_order_integral_images
135  */
136  void
137  setSecondOrderComputation (bool compute_second_order_integral_images);
138 
139  /** \brief Set the input data to compute the integral image for
140  * \param[in] data the input data
141  * \param[in] width the width of the data
142  * \param[in] height the height of the data
143  * \param[in] element_stride the element stride of the data
144  * \param[in] row_stride the row stride of the data
145  */
146  void
147  setInput (const DataType * data,
148  unsigned width, unsigned height, unsigned element_stride, unsigned row_stride);
149 
150  /** \brief Compute the first order sum within a given rectangle
151  * \param[in] start_x x position of rectangle
152  * \param[in] start_y y position of rectangle
153  * \param[in] width width of rectangle
154  * \param[in] height height of rectangle
155  */
156  inline ElementType
157  getFirstOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
158 
159  /** \brief Compute the first order sum within a given rectangle
160  * \param[in] start_x x position of the start of the rectangle
161  * \param[in] start_y x position of the start of the rectangle
162  * \param[in] end_x x position of the end of the rectangle
163  * \param[in] end_y x position of the end of the rectangle
164  */
165  inline ElementType
166  getFirstOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
167 
168  /** \brief Compute the second order sum within a given rectangle
169  * \param[in] start_x x position of rectangle
170  * \param[in] start_y y position of rectangle
171  * \param[in] width width of rectangle
172  * \param[in] height height of rectangle
173  */
174  inline SecondOrderType
175  getSecondOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
176 
177  /** \brief Compute the second order sum within a given rectangle
178  * \param[in] start_x x position of the start of the rectangle
179  * \param[in] start_y x position of the start of the rectangle
180  * \param[in] end_x x position of the end of the rectangle
181  * \param[in] end_y x position of the end of the rectangle
182  */
183  inline SecondOrderType
184  getSecondOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
185 
186  /** \brief Compute the number of finite elements within a given rectangle
187  * \param[in] start_x x position of rectangle
188  * \param[in] start_y y position of rectangle
189  * \param[in] width width of rectangle
190  * \param[in] height height of rectangle
191  */
192  inline unsigned
193  getFiniteElementsCount (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
194 
195  /** \brief Compute the number of finite elements within a given rectangle
196  * \param[in] start_x x position of the start of the rectangle
197  * \param[in] start_y x position of the start of the rectangle
198  * \param[in] end_x x position of the end of the rectangle
199  * \param[in] end_y x position of the end of the rectangle
200  */
201  inline unsigned
202  getFiniteElementsCountSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
203 
204  private:
205  using InputType = Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::Type, Dimension, 1>;
206 
207  /** \brief Compute the actual integral image data
208  * \param[in] data the input data
209  * \param[in] element_stride the element stride of the data
210  * \param[in] row_stride the row stride of the data
211  */
212  void
213  computeIntegralImages (const DataType * data, unsigned row_stride, unsigned element_stride);
214 
215  std::vector<ElementType, Eigen::aligned_allocator<ElementType> > first_order_integral_image_;
216  std::vector<SecondOrderType, Eigen::aligned_allocator<SecondOrderType> > second_order_integral_image_;
217  std::vector<unsigned> finite_values_integral_image_;
218 
219  /** \brief The width of the 2d input data array */
220  unsigned width_{1};
221  /** \brief The height of the 2d input data array */
222  unsigned height_{1};
223 
224  /** \brief Indicates whether second order integral images are available **/
225  bool compute_second_order_integral_images_;
226  };
227 
228  /**
229  * \brief partial template specialization for integral images with just one channel.
230  */
231  template <class DataType>
232  class IntegralImage2D <DataType, 1>
233  {
234  public:
235  using Ptr = shared_ptr<IntegralImage2D<DataType, 1>>;
236  using ConstPtr = shared_ptr<const IntegralImage2D<DataType, 1>>;
237 
238  static const unsigned second_order_size = 1;
241 
242  /** \brief Constructor for an Integral Image
243  * \param[in] compute_second_order_integral_images set to true if we want to compute a second order image
244  */
245  IntegralImage2D (bool compute_second_order_integral_images) :
246  first_order_integral_image_ (),
247  second_order_integral_image_ (),
248 
249 
250  compute_second_order_integral_images_ (compute_second_order_integral_images)
251  {
252  }
253 
254  /** \brief Destructor */
255  virtual
256  ~IntegralImage2D () = default;
257 
258  /** \brief Set the input data to compute the integral image for
259  * \param[in] data the input data
260  * \param[in] width the width of the data
261  * \param[in] height the height of the data
262  * \param[in] element_stride the element stride of the data
263  * \param[in] row_stride the row stride of the data
264  */
265  void
266  setInput (const DataType * data,
267  unsigned width, unsigned height, unsigned element_stride, unsigned row_stride);
268 
269  /** \brief Compute the first order sum within a given rectangle
270  * \param[in] start_x x position of rectangle
271  * \param[in] start_y y position of rectangle
272  * \param[in] width width of rectangle
273  * \param[in] height height of rectangle
274  */
275  inline ElementType
276  getFirstOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
277 
278  /** \brief Compute the first order sum within a given rectangle
279  * \param[in] start_x x position of the start of the rectangle
280  * \param[in] start_y x position of the start of the rectangle
281  * \param[in] end_x x position of the end of the rectangle
282  * \param[in] end_y x position of the end of the rectangle
283  */
284  inline ElementType
285  getFirstOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
286 
287  /** \brief Compute the second order sum within a given rectangle
288  * \param[in] start_x x position of rectangle
289  * \param[in] start_y y position of rectangle
290  * \param[in] width width of rectangle
291  * \param[in] height height of rectangle
292  */
293  inline SecondOrderType
294  getSecondOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
295 
296  /** \brief Compute the second order sum within a given rectangle
297  * \param[in] start_x x position of the start of the rectangle
298  * \param[in] start_y x position of the start of the rectangle
299  * \param[in] end_x x position of the end of the rectangle
300  * \param[in] end_y x position of the end of the rectangle
301  */
302  inline SecondOrderType
303  getSecondOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
304 
305  /** \brief Compute the number of finite elements within a given rectangle
306  * \param[in] start_x x position of rectangle
307  * \param[in] start_y y position of rectangle
308  * \param[in] width width of rectangle
309  * \param[in] height height of rectangle
310  */
311  inline unsigned
312  getFiniteElementsCount (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
313 
314  /** \brief Compute the number of finite elements within a given rectangle
315  * \param[in] start_x x position of the start of the rectangle
316  * \param[in] start_y x position of the start of the rectangle
317  * \param[in] end_x x position of the end of the rectangle
318  * \param[in] end_y x position of the end of the rectangle
319  */
320  inline unsigned
321  getFiniteElementsCountSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
322 
323  private:
324  // using InputType = typename IntegralImageTypeTraits<DataType>::Type;
325 
326  /** \brief Compute the actual integral image data
327  * \param[in] data the input data
328  * \param[in] element_stride the element stride of the data
329  * \param[in] row_stride the row stride of the data
330  */
331  void
332  computeIntegralImages (const DataType * data, unsigned row_stride, unsigned element_stride);
333 
334  std::vector<ElementType, Eigen::aligned_allocator<ElementType> > first_order_integral_image_;
335  std::vector<SecondOrderType, Eigen::aligned_allocator<SecondOrderType> > second_order_integral_image_;
336  std::vector<unsigned> finite_values_integral_image_;
337 
338  /** \brief The width of the 2d input data array */
339  unsigned width_{1};
340  /** \brief The height of the 2d input data array */
341  unsigned height_{1};
342 
343  /** \brief Indicates whether second order integral images are available **/
344  bool compute_second_order_integral_images_;
345  };
346  }
347 
348 #include <pcl/features/impl/integral_image2D.hpp>
typename IntegralImageTypeTraits< DataType >::IntegralType SecondOrderType
shared_ptr< IntegralImage2D< DataType, 1 > > Ptr
virtual ~IntegralImage2D()=default
Destructor.
IntegralImage2D(bool compute_second_order_integral_images)
Constructor for an Integral Image.
typename IntegralImageTypeTraits< DataType >::IntegralType ElementType
shared_ptr< const IntegralImage2D< DataType, 1 > > ConstPtr
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.
static const unsigned second_order_size
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.
virtual ~IntegralImage2D()=default
Destructor.
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.
IntegralImage2D(bool compute_second_order_integral_images)
Constructor for an Integral Image.
shared_ptr< IntegralImage2D< DataType, Dimension > > Ptr
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.
shared_ptr< const IntegralImage2D< DataType, Dimension > > ConstPtr
Defines functions, macros and traits for allocating and using memory.