Point Cloud Library (PCL)  1.9.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 <vector>
43 
44 #include <boost/shared_ptr.hpp>
45 
46 namespace pcl
47 {
48  template <typename DataType>
50  {
51  using Type = DataType;
52  using IntegralType = DataType;
53  };
54 
55  template <>
57  {
58  using Type = float;
59  using IntegralType = double;
60  };
61 
62  template <>
64  {
65  using Type = char;
66  using IntegralType = int;
67  };
68 
69  template <>
71  {
72  using Type = short;
73  using IntegralType = long;
74  };
75 
76  template <>
77  struct IntegralImageTypeTraits<unsigned short>
78  {
79  using Type = unsigned short;
80  using IntegralType = unsigned long;
81  };
82 
83  template <>
84  struct IntegralImageTypeTraits<unsigned char>
85  {
86  using Type = unsigned char;
87  using IntegralType = unsigned int;
88  };
89 
90  template <>
92  {
93  using Type = int;
94  using IntegralType = long;
95  };
96 
97  template <>
98  struct IntegralImageTypeTraits<unsigned int>
99  {
100  using Type = unsigned int;
101  using IntegralType = unsigned long;
102  };
103 
104  /** \brief Determines an integral image representation for a given organized data array
105  * \author Suat Gedikli
106  */
107  template <class DataType, unsigned Dimension>
109  {
110  public:
111  using Ptr = boost::shared_ptr<IntegralImage2D<DataType, Dimension>>;
112  static const unsigned second_order_size = (Dimension * (Dimension + 1)) >> 1;
113  using ElementType = Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::IntegralType, Dimension, 1>;
114  using SecondOrderType = Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::IntegralType, second_order_size, 1>;
115 
116  /** \brief Constructor for an Integral Image
117  * \param[in] compute_second_order_integral_images set to true if we want to compute a second order image
118  */
119  IntegralImage2D (bool compute_second_order_integral_images) :
120  first_order_integral_image_ (),
121  second_order_integral_image_ (),
122  width_ (1),
123  height_ (1),
124  compute_second_order_integral_images_ (compute_second_order_integral_images)
125  {
126  }
127 
128  /** \brief Destructor */
129  virtual
131 
132  /** \brief sets the computation for second order integral images on or off.
133  * \param compute_second_order_integral_images
134  */
135  void
136  setSecondOrderComputation (bool compute_second_order_integral_images);
137 
138  /** \brief Set the input data to compute the integral image for
139  * \param[in] data the input data
140  * \param[in] width the width of the data
141  * \param[in] height the height of the data
142  * \param[in] element_stride the element stride of the data
143  * \param[in] row_stride the row stride of the data
144  */
145  void
146  setInput (const DataType * data,
147  unsigned width, unsigned height, unsigned element_stride, unsigned row_stride);
148 
149  /** \brief Compute the first order sum within a given rectangle
150  * \param[in] start_x x position of rectangle
151  * \param[in] start_y y position of rectangle
152  * \param[in] width width of rectangle
153  * \param[in] height height of rectangle
154  */
155  inline ElementType
156  getFirstOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
157 
158  /** \brief Compute the first order sum within a given rectangle
159  * \param[in] start_x x position of the start of the rectangle
160  * \param[in] start_y x position of the start of the rectangle
161  * \param[in] end_x x position of the end of the rectangle
162  * \param[in] end_y x position of the end of the rectangle
163  */
164  inline ElementType
165  getFirstOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
166 
167  /** \brief Compute the second order sum within a given rectangle
168  * \param[in] start_x x position of rectangle
169  * \param[in] start_y y position of rectangle
170  * \param[in] width width of rectangle
171  * \param[in] height height of rectangle
172  */
173  inline SecondOrderType
174  getSecondOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
175 
176  /** \brief Compute the second order sum within a given rectangle
177  * \param[in] start_x x position of the start of the rectangle
178  * \param[in] start_y x position of the start of the rectangle
179  * \param[in] end_x x position of the end of the rectangle
180  * \param[in] end_y x position of the end of the rectangle
181  */
182  inline SecondOrderType
183  getSecondOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
184 
185  /** \brief Compute the number of finite elements within a given rectangle
186  * \param[in] start_x x position of rectangle
187  * \param[in] start_y y position of rectangle
188  * \param[in] width width of rectangle
189  * \param[in] height height of rectangle
190  */
191  inline unsigned
192  getFiniteElementsCount (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
193 
194  /** \brief Compute the number of finite elements within a given rectangle
195  * \param[in] start_x x position of the start of the rectangle
196  * \param[in] start_y x position of the start of the rectangle
197  * \param[in] end_x x position of the end of the rectangle
198  * \param[in] end_y x position of the end of the rectangle
199  */
200  inline unsigned
201  getFiniteElementsCountSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
202 
203  private:
204  using InputType = Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::Type, Dimension, 1>;
205 
206  /** \brief Compute the actual integral image data
207  * \param[in] data the input data
208  * \param[in] element_stride the element stride of the data
209  * \param[in] row_stride the row stride of the data
210  */
211  void
212  computeIntegralImages (const DataType * data, unsigned row_stride, unsigned element_stride);
213 
214  std::vector<ElementType, Eigen::aligned_allocator<ElementType> > first_order_integral_image_;
215  std::vector<SecondOrderType, Eigen::aligned_allocator<SecondOrderType> > second_order_integral_image_;
216  std::vector<unsigned> finite_values_integral_image_;
217 
218  /** \brief The width of the 2d input data array */
219  unsigned width_;
220  /** \brief The height of the 2d input data array */
221  unsigned height_;
222 
223  /** \brief Indicates whether second order integral images are available **/
224  bool compute_second_order_integral_images_;
225  };
226 
227  /**
228  * \brief partial template specialization for integral images with just one channel.
229  */
230  template <class DataType>
231  class IntegralImage2D <DataType, 1>
232  {
233  public:
234  using Ptr = boost::shared_ptr<IntegralImage2D<DataType, 1>>;
235 
236  static const unsigned second_order_size = 1;
239 
240  /** \brief Constructor for an Integral Image
241  * \param[in] compute_second_order_integral_images set to true if we want to compute a second order image
242  */
243  IntegralImage2D (bool compute_second_order_integral_images) :
244  first_order_integral_image_ (),
245  second_order_integral_image_ (),
246 
247  width_ (1), height_ (1),
248  compute_second_order_integral_images_ (compute_second_order_integral_images)
249  {
250  }
251 
252  /** \brief Destructor */
253  virtual
255 
256  /** \brief Set the input data to compute the integral image for
257  * \param[in] data the input data
258  * \param[in] width the width of the data
259  * \param[in] height the height of the data
260  * \param[in] element_stride the element stride of the data
261  * \param[in] row_stride the row stride of the data
262  */
263  void
264  setInput (const DataType * data,
265  unsigned width, unsigned height, unsigned element_stride, unsigned row_stride);
266 
267  /** \brief Compute the first order sum within a given rectangle
268  * \param[in] start_x x position of rectangle
269  * \param[in] start_y y position of rectangle
270  * \param[in] width width of rectangle
271  * \param[in] height height of rectangle
272  */
273  inline ElementType
274  getFirstOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
275 
276  /** \brief Compute the first order sum within a given rectangle
277  * \param[in] start_x x position of the start of the rectangle
278  * \param[in] start_y x position of the start of the rectangle
279  * \param[in] end_x x position of the end of the rectangle
280  * \param[in] end_y x position of the end of the rectangle
281  */
282  inline ElementType
283  getFirstOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
284 
285  /** \brief Compute the second order sum within a given rectangle
286  * \param[in] start_x x position of rectangle
287  * \param[in] start_y y position of rectangle
288  * \param[in] width width of rectangle
289  * \param[in] height height of rectangle
290  */
291  inline SecondOrderType
292  getSecondOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
293 
294  /** \brief Compute the second order sum within a given rectangle
295  * \param[in] start_x x position of the start of the rectangle
296  * \param[in] start_y x position of the start of the rectangle
297  * \param[in] end_x x position of the end of the rectangle
298  * \param[in] end_y x position of the end of the rectangle
299  */
300  inline SecondOrderType
301  getSecondOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
302 
303  /** \brief Compute the number of finite elements within a given rectangle
304  * \param[in] start_x x position of rectangle
305  * \param[in] start_y y position of rectangle
306  * \param[in] width width of rectangle
307  * \param[in] height height of rectangle
308  */
309  inline unsigned
310  getFiniteElementsCount (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
311 
312  /** \brief Compute the number of finite elements within a given rectangle
313  * \param[in] start_x x position of the start of the rectangle
314  * \param[in] start_y x position of the start of the rectangle
315  * \param[in] end_x x position of the end of the rectangle
316  * \param[in] end_y x position of the end of the rectangle
317  */
318  inline unsigned
319  getFiniteElementsCountSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
320 
321  private:
322  // using InputType = typename IntegralImageTypeTraits<DataType>::Type;
323 
324  /** \brief Compute the actual integral image data
325  * \param[in] data the input data
326  * \param[in] element_stride the element stride of the data
327  * \param[in] row_stride the row stride of the data
328  */
329  void
330  computeIntegralImages (const DataType * data, unsigned row_stride, unsigned element_stride);
331 
332  std::vector<ElementType, Eigen::aligned_allocator<ElementType> > first_order_integral_image_;
333  std::vector<SecondOrderType, Eigen::aligned_allocator<SecondOrderType> > second_order_integral_image_;
334  std::vector<unsigned> finite_values_integral_image_;
335 
336  /** \brief The width of the 2d input data array */
337  unsigned width_;
338  /** \brief The height of the 2d input data array */
339  unsigned height_;
340 
341  /** \brief Indicates whether second order integral images are available **/
342  bool compute_second_order_integral_images_;
343  };
344  }
345 
346 #include <pcl/features/impl/integral_image2D.hpp>
typename IntegralImageTypeTraits< DataType >::IntegralType ElementType
virtual ~IntegralImage2D()
Destructor.
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:45
virtual ~IntegralImage2D()
Destructor.
IntegralImage2D(bool compute_second_order_integral_images)
Constructor for an Integral Image.
IntegralImage2D(bool compute_second_order_integral_images)
Constructor for an Integral Image.
typename IntegralImageTypeTraits< DataType >::IntegralType SecondOrderType
Determines an integral image representation for a given organized data array.
boost::shared_ptr< IntegralImage2D< float, Dimension >> Ptr
boost::shared_ptr< IntegralImage2D< DataType, 1 >> Ptr
Eigen::Matrix< typename IntegralImageTypeTraits< float >::IntegralType, second_order_size, 1 > SecondOrderType
Eigen::Matrix< typename IntegralImageTypeTraits< float >::IntegralType, Dimension, 1 > ElementType