Point Cloud Library (PCL)  1.12.1-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  width_ (1),
125  height_ (1),
126  compute_second_order_integral_images_ (compute_second_order_integral_images)
127  {
128  }
129 
130  /** \brief Destructor */
131  virtual
132  ~IntegralImage2D () = default;
133 
134  /** \brief sets the computation for second order integral images on or off.
135  * \param compute_second_order_integral_images
136  */
137  void
138  setSecondOrderComputation (bool compute_second_order_integral_images);
139 
140  /** \brief Set the input data to compute the integral image for
141  * \param[in] data the input data
142  * \param[in] width the width of the data
143  * \param[in] height the height of the data
144  * \param[in] element_stride the element stride of the data
145  * \param[in] row_stride the row stride of the data
146  */
147  void
148  setInput (const DataType * data,
149  unsigned width, unsigned height, unsigned element_stride, unsigned row_stride);
150 
151  /** \brief Compute the first order sum within a given rectangle
152  * \param[in] start_x x position of rectangle
153  * \param[in] start_y y position of rectangle
154  * \param[in] width width of rectangle
155  * \param[in] height height of rectangle
156  */
157  inline ElementType
158  getFirstOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
159 
160  /** \brief Compute the first order sum within a given rectangle
161  * \param[in] start_x x position of the start of the rectangle
162  * \param[in] start_y x position of the start of the rectangle
163  * \param[in] end_x x position of the end of the rectangle
164  * \param[in] end_y x position of the end of the rectangle
165  */
166  inline ElementType
167  getFirstOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
168 
169  /** \brief Compute the second order sum within a given rectangle
170  * \param[in] start_x x position of rectangle
171  * \param[in] start_y y position of rectangle
172  * \param[in] width width of rectangle
173  * \param[in] height height of rectangle
174  */
175  inline SecondOrderType
176  getSecondOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
177 
178  /** \brief Compute the second order sum within a given rectangle
179  * \param[in] start_x x position of the start of the rectangle
180  * \param[in] start_y x position of the start of the rectangle
181  * \param[in] end_x x position of the end of the rectangle
182  * \param[in] end_y x position of the end of the rectangle
183  */
184  inline SecondOrderType
185  getSecondOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
186 
187  /** \brief Compute the number of finite elements within a given rectangle
188  * \param[in] start_x x position of rectangle
189  * \param[in] start_y y position of rectangle
190  * \param[in] width width of rectangle
191  * \param[in] height height of rectangle
192  */
193  inline unsigned
194  getFiniteElementsCount (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
195 
196  /** \brief Compute the number of finite elements within a given rectangle
197  * \param[in] start_x x position of the start of the rectangle
198  * \param[in] start_y x position of the start of the rectangle
199  * \param[in] end_x x position of the end of the rectangle
200  * \param[in] end_y x position of the end of the rectangle
201  */
202  inline unsigned
203  getFiniteElementsCountSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
204 
205  private:
206  using InputType = Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::Type, Dimension, 1>;
207 
208  /** \brief Compute the actual integral image data
209  * \param[in] data the input data
210  * \param[in] element_stride the element stride of the data
211  * \param[in] row_stride the row stride of the data
212  */
213  void
214  computeIntegralImages (const DataType * data, unsigned row_stride, unsigned element_stride);
215 
216  std::vector<ElementType, Eigen::aligned_allocator<ElementType> > first_order_integral_image_;
217  std::vector<SecondOrderType, Eigen::aligned_allocator<SecondOrderType> > second_order_integral_image_;
218  std::vector<unsigned> finite_values_integral_image_;
219 
220  /** \brief The width of the 2d input data array */
221  unsigned width_;
222  /** \brief The height of the 2d input data array */
223  unsigned height_;
224 
225  /** \brief Indicates whether second order integral images are available **/
226  bool compute_second_order_integral_images_;
227  };
228 
229  /**
230  * \brief partial template specialization for integral images with just one channel.
231  */
232  template <class DataType>
233  class IntegralImage2D <DataType, 1>
234  {
235  public:
236  using Ptr = shared_ptr<IntegralImage2D<DataType, 1>>;
237  using ConstPtr = shared_ptr<const IntegralImage2D<DataType, 1>>;
238 
239  static const unsigned second_order_size = 1;
242 
243  /** \brief Constructor for an Integral Image
244  * \param[in] compute_second_order_integral_images set to true if we want to compute a second order image
245  */
246  IntegralImage2D (bool compute_second_order_integral_images) :
247  first_order_integral_image_ (),
248  second_order_integral_image_ (),
249 
250  width_ (1), height_ (1),
251  compute_second_order_integral_images_ (compute_second_order_integral_images)
252  {
253  }
254 
255  /** \brief Destructor */
256  virtual
257  ~IntegralImage2D () = default;
258 
259  /** \brief Set the input data to compute the integral image for
260  * \param[in] data the input data
261  * \param[in] width the width of the data
262  * \param[in] height the height of the data
263  * \param[in] element_stride the element stride of the data
264  * \param[in] row_stride the row stride of the data
265  */
266  void
267  setInput (const DataType * data,
268  unsigned width, unsigned height, unsigned element_stride, unsigned row_stride);
269 
270  /** \brief Compute the first order sum within a given rectangle
271  * \param[in] start_x x position of rectangle
272  * \param[in] start_y y position of rectangle
273  * \param[in] width width of rectangle
274  * \param[in] height height of rectangle
275  */
276  inline ElementType
277  getFirstOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
278 
279  /** \brief Compute the first order sum within a given rectangle
280  * \param[in] start_x x position of the start of the rectangle
281  * \param[in] start_y x position of the start of the rectangle
282  * \param[in] end_x x position of the end of the rectangle
283  * \param[in] end_y x position of the end of the rectangle
284  */
285  inline ElementType
286  getFirstOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
287 
288  /** \brief Compute the second order sum within a given rectangle
289  * \param[in] start_x x position of rectangle
290  * \param[in] start_y y position of rectangle
291  * \param[in] width width of rectangle
292  * \param[in] height height of rectangle
293  */
294  inline SecondOrderType
295  getSecondOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
296 
297  /** \brief Compute the second order sum within a given rectangle
298  * \param[in] start_x x position of the start of the rectangle
299  * \param[in] start_y x position of the start of the rectangle
300  * \param[in] end_x x position of the end of the rectangle
301  * \param[in] end_y x position of the end of the rectangle
302  */
303  inline SecondOrderType
304  getSecondOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
305 
306  /** \brief Compute the number of finite elements within a given rectangle
307  * \param[in] start_x x position of rectangle
308  * \param[in] start_y y position of rectangle
309  * \param[in] width width of rectangle
310  * \param[in] height height of rectangle
311  */
312  inline unsigned
313  getFiniteElementsCount (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
314 
315  /** \brief Compute the number of finite elements within a given rectangle
316  * \param[in] start_x x position of the start of the rectangle
317  * \param[in] start_y x position of the start of the rectangle
318  * \param[in] end_x x position of the end of the rectangle
319  * \param[in] end_y x position of the end of the rectangle
320  */
321  inline unsigned
322  getFiniteElementsCountSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
323 
324  private:
325  // using InputType = typename IntegralImageTypeTraits<DataType>::Type;
326 
327  /** \brief Compute the actual integral image data
328  * \param[in] data the input data
329  * \param[in] element_stride the element stride of the data
330  * \param[in] row_stride the row stride of the data
331  */
332  void
333  computeIntegralImages (const DataType * data, unsigned row_stride, unsigned element_stride);
334 
335  std::vector<ElementType, Eigen::aligned_allocator<ElementType> > first_order_integral_image_;
336  std::vector<SecondOrderType, Eigen::aligned_allocator<SecondOrderType> > second_order_integral_image_;
337  std::vector<unsigned> finite_values_integral_image_;
338 
339  /** \brief The width of the 2d input data array */
340  unsigned width_;
341  /** \brief The height of the 2d input data array */
342  unsigned height_;
343 
344  /** \brief Indicates whether second order integral images are available **/
345  bool compute_second_order_integral_images_;
346  };
347  }
348 
349 #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.