Point Cloud Library (PCL)  1.7.0
gaussian.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_GAUSSIAN_KERNEL
41 #define PCL_GAUSSIAN_KERNEL
42 
43 #include <sstream>
44 #include <pcl/common/eigen.h>
45 #include <pcl/point_cloud.h>
46 #include <boost/function.hpp>
47 
48 namespace pcl
49 {
50  /** Class GaussianKernel assembles all the method for computing,
51  * convolving, smoothing, gradients computing an image using
52  * a gaussian kernel. The image is stored in point cloud elements
53  * intensity member or rgb or...
54  * \author Nizar Sallem
55  * \ingroup common
56  */
57  class PCL_EXPORTS GaussianKernel
58  {
59  public:
60 
62 
63  static const unsigned MAX_KERNEL_WIDTH = 71;
64  /** Computes the gaussian kernel and dervative assiociated to sigma.
65  * The kernel and derivative width are adjusted according.
66  * \param[in] sigma
67  * \param[out] kernel the computed gaussian kernel
68  * \param[in] kernel_width the desired kernel width upper bond
69  * \throws pcl::KernelWidthTooSmallException
70  */
71  void
72  compute (float sigma,
73  Eigen::VectorXf &kernel,
74  unsigned kernel_width = MAX_KERNEL_WIDTH) const;
75 
76  /** Computes the gaussian kernel and dervative assiociated to sigma.
77  * The kernel and derivative width are adjusted according.
78  * \param[in] sigma
79  * \param[out] kernel the computed gaussian kernel
80  * \param[out] derivative the computed kernel derivative
81  * \param[in] kernel_width the desired kernel width upper bond
82  * \throws pcl::KernelWidthTooSmallException
83  */
84  void
85  compute (float sigma,
86  Eigen::VectorXf &kernel,
87  Eigen::VectorXf &derivative,
88  unsigned kernel_width = MAX_KERNEL_WIDTH) const;
89 
90  /** Convolve a float image rows by a given kernel.
91  * \param[in] kernel convolution kernel
92  * \param[in] input the image to convolve
93  * \param[out] output the convolved image
94  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
95  * output.cols () < input.cols () then output is resized to input sizes.
96  */
97  void
98  convolveRows (const pcl::PointCloud<float> &input,
99  const Eigen::VectorXf &kernel,
100  pcl::PointCloud<float> &output) const;
101 
102  /** Convolve a float image rows by a given kernel.
103  * \param[in] input the image to convolve
104  * \param[in] field_accessor a field accessor
105  * \param[in] kernel convolution kernel
106  * \param[out] output the convolved image
107  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
108  * output.cols () < input.cols () then output is resized to input sizes.
109  */
110  template <typename PointT> void
111  convolveRows (const pcl::PointCloud<PointT> &input,
112  boost::function <float (const PointT& p)> field_accessor,
113  const Eigen::VectorXf &kernel,
114  pcl::PointCloud<float> &output) const;
115 
116  /** Convolve a float image columns by a given kernel.
117  * \param[in] input the image to convolve
118  * \param[in] kernel convolution kernel
119  * \param[out] output the convolved image
120  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
121  * output.cols () < input.cols () then output is resized to input sizes.
122  */
123  void
124  convolveCols (const pcl::PointCloud<float> &input,
125  const Eigen::VectorXf &kernel,
126  pcl::PointCloud<float> &output) const;
127 
128  /** Convolve a float image columns by a given kernel.
129  * \param[in] input the image to convolve
130  * \param[in] field_accessor a field accessor
131  * \param[in] kernel convolution kernel
132  * \param[out] output the convolved image
133  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
134  * output.cols () < input.cols () then output is resized to input sizes.
135  */
136  template <typename PointT> void
137  convolveCols (const pcl::PointCloud<PointT> &input,
138  boost::function <float (const PointT& p)> field_accessor,
139  const Eigen::VectorXf &kernel,
140  pcl::PointCloud<float> &output) const;
141 
142  /** Convolve a float image in the 2 directions
143  * \param[in] horiz_kernel kernel for convolving rows
144  * \param[in] vert_kernel kernel for convolving columns
145  * \param[in] input image to convolve
146  * \param[out] output the convolved image
147  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
148  * output.cols () < input.cols () then output is resized to input sizes.
149  */
150  inline void
152  const Eigen::VectorXf &horiz_kernel,
153  const Eigen::VectorXf &vert_kernel,
154  pcl::PointCloud<float> &output) const
155  {
156  std::cout << ">>> convolve cpp" << std::endl;
157  pcl::PointCloud<float> tmp (input.width, input.height) ;
158  convolveRows (input, horiz_kernel, tmp);
159  convolveCols (tmp, vert_kernel, output);
160  std::cout << "<<< convolve cpp" << std::endl;
161  }
162 
163  /** Convolve a float image in the 2 directions
164  * \param[in] input image to convolve
165  * \param[in] field_accessor a field accessor
166  * \param[in] horiz_kernel kernel for convolving rows
167  * \param[in] vert_kernel kernel for convolving columns
168  * \param[out] output the convolved image
169  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
170  * output.cols () < input.cols () then output is resized to input sizes.
171  */
172  template <typename PointT> inline void
174  boost::function <float (const PointT& p)> field_accessor,
175  const Eigen::VectorXf &horiz_kernel,
176  const Eigen::VectorXf &vert_kernel,
177  pcl::PointCloud<float> &output) const
178  {
179  std::cout << ">>> convolve hpp" << std::endl;
180  pcl::PointCloud<float> tmp (input.width, input.height);
181  convolveRows<PointT>(input, field_accessor, horiz_kernel, tmp);
182  convolveCols(tmp, vert_kernel, output);
183  std::cout << "<<< convolve hpp" << std::endl;
184  }
185 
186  /** Computes float image gradients using a gaussian kernel and gaussian kernel
187  * derivative.
188  * \param[in] input image to compute gardients for
189  * \param[in] gaussian_kernel the gaussian kernel to be used
190  * \param[in] gaussian_kernel_derivative the associated derivative
191  * \param[out] grad_x gradient along X direction
192  * \param[out] grad_y gradient along Y direction
193  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
194  * output.cols () < input.cols () then output is resized to input sizes.
195  */
196  inline void
198  const Eigen::VectorXf &gaussian_kernel,
199  const Eigen::VectorXf &gaussian_kernel_derivative,
200  pcl::PointCloud<float> &grad_x,
201  pcl::PointCloud<float> &grad_y) const
202  {
203  convolve (input, gaussian_kernel_derivative, gaussian_kernel, grad_x);
204  convolve (input, gaussian_kernel, gaussian_kernel_derivative, grad_y);
205  }
206 
207  /** Computes float image gradients using a gaussian kernel and gaussian kernel
208  * derivative.
209  * \param[in] input image to compute gardients for
210  * \param[in] field_accessor a field accessor
211  * \param[in] gaussian_kernel the gaussian kernel to be used
212  * \param[in] gaussian_kernel_derivative the associated derivative
213  * \param[out] grad_x gradient along X direction
214  * \param[out] grad_y gradient along Y direction
215  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
216  * output.cols () < input.cols () then output is resized to input sizes.
217  */
218  template <typename PointT> inline void
220  boost::function <float (const PointT& p)> field_accessor,
221  const Eigen::VectorXf &gaussian_kernel,
222  const Eigen::VectorXf &gaussian_kernel_derivative,
223  pcl::PointCloud<float> &grad_x,
224  pcl::PointCloud<float> &grad_y) const
225  {
226  convolve<PointT> (input, field_accessor, gaussian_kernel_derivative, gaussian_kernel, grad_x);
227  convolve<PointT> (input, field_accessor, gaussian_kernel, gaussian_kernel_derivative, grad_y);
228  }
229 
230  /** Smooth image using a gaussian kernel.
231  * \param[in] input image
232  * \param[in] gaussian_kernel the gaussian kernel to be used
233  * \param[out] output the smoothed image
234  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
235  * output.cols () < input.cols () then output is resized to input sizes.
236  */
237  inline void
239  const Eigen::VectorXf &gaussian_kernel,
240  pcl::PointCloud<float> &output) const
241  {
242  convolve (input, gaussian_kernel, gaussian_kernel, output);
243  }
244 
245  /** Smooth image using a gaussian kernel.
246  * \param[in] input image
247  * \param[in] field_accessor a field accessor
248  * \param[in] gaussian_kernel the gaussian kernel to be used
249  * \param[out] output the smoothed image
250  * \note if output doesn't fit in input i.e. output.rows () < input.rows () or
251  * output.cols () < input.cols () then output is resized to input sizes.
252  */
253  template <typename PointT> inline void
255  boost::function <float (const PointT& p)> field_accessor,
256  const Eigen::VectorXf &gaussian_kernel,
257  pcl::PointCloud<float> &output) const
258  {
259  convolve<PointT> (input, field_accessor, gaussian_kernel, gaussian_kernel, output);
260  }
261  };
262 }
263 
264 #include <pcl/common/impl/gaussian.hpp>
265 
266 #endif // PCL_GAUSSIAN_KERNEL