Point Cloud Library (PCL)  1.7.0
convolution.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  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id$
37  *
38  */
39 
40 #ifndef PCL_FILTERS_CONVOLUTION_H_
41 #define PCL_FILTERS_CONVOLUTION_H_
42 
43 #include <pcl/common/eigen.h>
44 #include <pcl/common/point_operators.h>
45 #include <pcl/point_cloud.h>
46 #include <pcl/exceptions.h>
47 #include <pcl/pcl_base.h>
48 
49 namespace pcl
50 {
51  namespace filters
52  {
53  /** Convolution is a mathematical operation on two functions f and g,
54  * producing a third function that is typically viewed as a modified
55  * version of one of the original functions.
56  * see http://en.wikipedia.org/wiki/Convolution.
57  *
58  * The class provides rows, column and separate convolving operations
59  * of a point cloud.
60  * Columns and separate convolution is only allowed on organised
61  * point clouds.
62  *
63  * When convolving, computing the rows and cols elements at 1/2 kernel
64  * width distance from the borders is not defined. We allow for 3
65  * policies:
66  * - Ignoring: elements at special locations are filled with zero
67  * (default behaviour)
68  * - Mirroring: the missing rows or columns are obtained throug mirroring
69  * - Duplicating: the missing rows or columns are obtained throug
70  * duplicating
71  *
72  * \author Nizar Sallem
73  * \ingroup filters
74  */
75 
76  template <typename PointIn, typename PointOut>
78  {
79  public:
84  typedef boost::shared_ptr< Convolution<PointIn, PointOut> > Ptr;
85  typedef boost::shared_ptr< const Convolution<PointIn, PointOut> > ConstPtr;
86 
87 
88  /// The borders policy available
90  {
94  };
95  /// Constructor
96  Convolution ();
97  /// Empty destructor
99  /** \brief Provide a pointer to the input dataset
100  * \param cloud the const boost shared pointer to a PointCloud message
101  * \remark Will perform a deep copy
102  */
103  inline void
104  setInputCloud (const PointCloudInConstPtr& cloud) { input_ = cloud; }
105  /** Set convolving kernel
106  * \param[in] kernel convolving element
107  */
108  inline void
109  setKernel (const Eigen::ArrayXf& kernel) { kernel_ = kernel; }
110  /// Set the borders policy
111  void
112  setBordersPolicy (int policy) { borders_policy_ = policy; }
113  /// Get the borders policy
114  int
115  getBordersPolicy () { return (borders_policy_); }
116  /** \remark this is critical so please read it carefully.
117  * In 3D the next point in (u,v) coordinate can be really far so a distance
118  * threshold is used to keep us from ghost points.
119  * The value you set here is strongly related to the sensor. A good value for
120  * kinect data is 0.001 \default is std::numeric<float>::infinity ()
121  * \param[in] threshold maximum allowed distance between 2 juxtaposed points
122  */
123  inline void
124  setDistanceThreshold (const float& threshold) { distance_threshold_ = threshold; }
125  /// \return the distance threshold
126  inline const float &
127  getDistanceThreshold () const { return (distance_threshold_); }
128  /** \brief Initialize the scheduler and set the number of threads to use.
129  * \param nr_threads the number of hardware threads to use (0 sets the value back to automatic)
130  */
131  inline void
132  setNumberOfThreads (unsigned int nr_threads = 0) { threads_ = nr_threads; }
133  /** Convolve a float image rows by a given kernel.
134  * \param[in] kernel convolution kernel
135  * \param[out] output the convolved cloud
136  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
137  * output.cols () < input.cols () then output is resized to input sizes.
138  */
139  inline void
140  convolveRows (PointCloudOut& output);
141  /** Convolve a float image columns by a given kernel.
142  * \param[in] kernel convolution kernel
143  * \param[out] output the convolved image
144  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
145  * output.cols () < input.cols () then output is resized to input sizes.
146  */
147  inline void
148  convolveCols (PointCloudOut& output);
149  /** Convolve point cloud with an horizontal kernel along rows
150  * then vertical kernel along columns : convolve separately.
151  * \param[in] h_kernel kernel for convolving rows
152  * \param[in] v_kernel kernel for convolving columns
153  * \param[out] output the convolved cloud
154  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
155  * output.cols () < input.cols () then output is resized to input sizes.
156  */
157  inline void
158  convolve (const Eigen::ArrayXf& h_kernel, const Eigen::ArrayXf& v_kernel, PointCloudOut& output);
159  /** Convolve point cloud with same kernel along rows and columns separately.
160  * \param[out] output the convolved cloud
161  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
162  * output.cols () < input.cols () then output is resized to input sizes.
163  */
164  inline void
165  convolve (PointCloudOut& output);
166 
167  protected:
168  /// \brief convolve rows and ignore borders
169  void
170  convolve_rows (PointCloudOut& output);
171  /// \brief convolve cols and ignore borders
172  void
173  convolve_cols (PointCloudOut& output);
174  /// \brief convolve rows and mirror borders
175  void
177  /// \brief convolve cols and mirror borders
178  void
180  /// \brief convolve rows and duplicate borders
181  void
183  /// \brief convolve cols and duplicate borders
184  void
186  /** init compute is an internal method called before computation
187  * \param[in] kernel convolution kernel to be used
188  * \throw pcl::InitFailedException
189  */
190  void
191  initCompute (PointCloudOut& output);
192  private:
193  /** \return the result of convolution of point at (\ai, \aj)
194  * \note no test on finity is performed
195  */
196  inline PointOut
197  convolveOneRowDense (int i, int j);
198  /** \return the result of convolution of point at (\ai, \aj)
199  * \note no test on finity is performed
200  */
201  inline PointOut
202  convolveOneColDense (int i, int j);
203  /** \return the result of convolution of point at (\ai, \aj)
204  * \note only finite points within \a distance_threshold_ are accounted
205  */
206  inline PointOut
207  convolveOneRowNonDense (int i, int j);
208  /** \return the result of convolution of point at (\ai, \aj)
209  * \note only finite points within \a distance_threshold_ are accounted
210  */
211  inline PointOut
212  convolveOneColNonDense (int i, int j);
213 
214  /// Border policy
215  int borders_policy_;
216  /// Threshold distance between adjacent points
217  float distance_threshold_;
218  /// Pointer to the input cloud
219  PointCloudInConstPtr input_;
220  /// convolution kernel
221  Eigen::ArrayXf kernel_;
222  /// half kernel size
223  int half_width_;
224  /// kernel size - 1
225  int kernel_width_;
226  protected:
227  /** \brief The number of threads the scheduler should use. */
228  unsigned int threads_;
229 
230  void
231  makeInfinite (PointOut& p)
232  {
233  p.x = p.y = p.z = std::numeric_limits<float>::quiet_NaN ();
234  }
235  };
236  }
237 }
238 
239 #include <pcl/filters/impl/convolution.hpp>
240 
241 #endif