Point Cloud Library (PCL)  1.7.0
convolution_3d.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2012, 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_3D_H
41 #define PCL_FILTERS_CONVOLUTION_3D_H
42 
43 #include <pcl/pcl_base.h>
44 #include <pcl/filters/boost.h>
45 #include <pcl/search/pcl_search.h>
46 
47 namespace pcl
48 {
49  namespace filters
50  {
51  /** \brief Class ConvolvingKernel base class for all convolving kernels
52  * \ingroup filters
53  */
54  template<typename PointInT, typename PointOutT>
56  {
57  public:
58  typedef boost::shared_ptr<ConvolvingKernel<PointInT, PointOutT> > Ptr;
59  typedef boost::shared_ptr<const ConvolvingKernel<PointInT, PointOutT> > ConstPtr;
60 
62 
63  /// \brief empty constructor
65 
66  /// \brief empty destructor
67  virtual ~ConvolvingKernel () {}
68 
69  /** \brief Set input cloud
70  * \param[in] input source point cloud
71  */
72  void
73  setInputCloud (const PointCloudInConstPtr& input) { input_ = input; }
74 
75  /** \brief Convolve point at the center of this local information
76  * \param[in] indices indices of the point in the source point cloud
77  * \param[in] distances euclidean distance squared from the query point
78  * \return the convolved point
79  */
80  virtual PointOutT
81  operator() (const std::vector<int>& indices, const std::vector<float>& distances) = 0;
82 
83  /** \brief Must call this methode before doing any computation
84  * \note make sure to override this with at least
85  * \code
86  * bool initCompute ()
87  * {
88  * return (true);
89  * }
90  * \endcode
91  * in your kernel interface, else you are going nowhere!
92  */
93  virtual bool
94  initCompute () { return false; }
95 
96  /** \brief Utility function that annihilates a point making it fail the \ref pcl::isFinite test
97  * \param[in/out] p point to annihilate
98  */
99  static void
100  makeInfinite (PointOutT& p)
101  {
102  p.x = p.y = p.z = std::numeric_limits<float>::quiet_NaN ();
103  }
104 
105  protected:
106  /// source cloud
108  };
109 
110  /** \brief Gaussian kernel implementation interface
111  * Use this as implementation reference
112  * \ingroup filters
113  */
114  template<typename PointInT, typename PointOutT>
115  class GaussianKernel : public ConvolvingKernel <PointInT, PointOutT>
116  {
117  public:
122  typedef boost::shared_ptr<GaussianKernel<PointInT, PointOutT> > Ptr;
123  typedef boost::shared_ptr<GaussianKernel<PointInT, PointOutT> > ConstPtr;
124 
125  /** Default constructor */
127  : ConvolvingKernel <PointInT, PointOutT> ()
128  , sigma_ (0)
129  , threshold_ (std::numeric_limits<float>::infinity ())
130  {}
131 
132  virtual ~GaussianKernel () {}
133 
134  /** Set the sigma parameter of the Gaussian
135  * \param[in] sigma
136  */
137  inline void
138  setSigma (float sigma) { sigma_ = sigma; }
139 
140  /** Set the distance threshold relative to a sigma factor i.e. points such as
141  * ||pi - q|| > sigma_coefficient^2 * sigma^2 are not considered.
142  */
143  inline void
144  setThresholdRelativeToSigma (float sigma_coefficient)
145  {
146  sigma_coefficient_.reset (sigma_coefficient);
147  }
148 
149  /** Set the distance threshold such as pi, ||pi - q|| > threshold are not considered. */
150  inline void
151  setThreshold (float threshold) { threshold_ = threshold; }
152 
153  /** Must call this methode before doing any computation */
154  bool initCompute ();
155 
156  virtual PointOutT
157  operator() (const std::vector<int>& indices, const std::vector<float>& distances);
158 
159  protected:
160  float sigma_;
161  float sigma_sqr_;
162  float threshold_;
163  boost::optional<float> sigma_coefficient_;
164  };
165 
166  /** \brief Gaussian kernel implementation interface with RGB channel handling
167  * Use this as implementation reference
168  * \ingroup filters
169  */
170  template<typename PointInT, typename PointOutT>
171  class GaussianKernelRGB : public GaussianKernel <PointInT, PointOutT>
172  {
173  public:
180  typedef boost::shared_ptr<GaussianKernelRGB<PointInT, PointOutT> > Ptr;
181  typedef boost::shared_ptr<GaussianKernelRGB<PointInT, PointOutT> > ConstPtr;
182 
183  /** Default constructor */
185  : GaussianKernel <PointInT, PointOutT> ()
186  {}
187 
189 
190  PointOutT
191  operator() (const std::vector<int>& indices, const std::vector<float>& distances);
192  };
193 
194  /** Convolution3D handles the non organized case where width and height are unknown or if you
195  * are only interested in convolving based on local neighborhood information.
196  * The convolving kernel MUST be a radial symmetric and implement \ref ConvolvingKernel
197  * interface.
198  */
199  template <typename PointIn, typename PointOut, typename KernelT>
200  class Convolution3D : public pcl::PCLBase <PointIn>
201  {
202  public:
208  typedef boost::shared_ptr<Convolution3D<PointIn, PointOut, KernelT> > Ptr;
209  typedef boost::shared_ptr<Convolution3D<PointIn, PointOut, KernelT> > ConstPtr;
210 
213 
214  /** \brief Constructor */
215  Convolution3D ();
216 
217  /** \brief Empty destructor */
219 
220  /** \brief Initialize the scheduler and set the number of threads to use.
221  * \param nr_threads the number of hardware threads to use (0 sets the value back to automatic)
222  */
223  inline void
224  setNumberOfThreads (unsigned int nr_threads = 0) { threads_ = nr_threads; }
225 
226  /** \brief Set convolving kernel
227  * \param[in] kernel convolving element
228  */
229  inline void
230  setKernel (const KernelT& kernel) { kernel_ = kernel; }
231 
232  /** \brief Provide a pointer to the input dataset that we need to estimate features at every point for.
233  * \param cloud the const boost shared pointer to a PointCloud message
234  */
235  inline void
236  setSearchSurface (const PointCloudInConstPtr &cloud) { surface_ = cloud; }
237 
238  /** \brief Get a pointer to the surface point cloud dataset. */
239  inline PointCloudInConstPtr
240  getSearchSurface () { return (surface_); }
241 
242  /** \brief Provide a pointer to the search object.
243  * \param tree a pointer to the spatial search object.
244  */
245  inline void
246  setSearchMethod (const KdTreePtr &tree) { tree_ = tree; }
247 
248  /** \brief Get a pointer to the search method used. */
249  inline KdTreePtr
250  getSearchMethod () { return (tree_); }
251 
252  /** \brief Set the sphere radius that is to be used for determining the nearest neighbors
253  * \param radius the sphere radius used as the maximum distance to consider a point a neighbor
254  */
255  inline void
256  setRadiusSearch (double radius) { search_radius_ = radius; }
257 
258  /** \brief Get the sphere radius used for determining the neighbors. */
259  inline double
261 
262  /** Convolve point cloud.
263  * \param[out] output the convolved cloud
264  */
265  void
266  convolve (PointCloudOut& output);
267 
268  protected:
269  /** \brief initialize computation */
270  bool initCompute ();
271 
272  /** \brief An input point cloud describing the surface that is to be used for nearest neighbors estimation. */
274 
275  /** \brief A pointer to the spatial search object. */
277 
278  /** \brief The nearest neighbors search radius for each point. */
280 
281  /** \brief number of threads */
282  unsigned int threads_;
283 
284  /** \brief convlving kernel */
285  KernelT kernel_;
286  };
287  }
288 }
289 
290 #include <pcl/filters/impl/convolution_3d.hpp>
291 
292 #endif // PCL_FILTERS_CONVOLUTION_3D_H