Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mls.h
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2009-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 Willow Garage, Inc. 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: mls.h 6439 2012-07-17 07:13:58Z aichim $
37  *
38  */
39 
40 #ifndef PCL_MLS_H_
41 #define PCL_MLS_H_
42 
43 // PCL includes
44 #include <pcl/pcl_base.h>
45 #include <boost/bind.hpp>
46 #include <boost/function.hpp>
47 #include <boost/random.hpp>
48 #include <pcl/search/pcl_search.h>
49 #include <pcl/common/common.h>
50 #include <pcl/surface/processing.h>
51 
52 #include <Eigen/SVD>
53 
54 namespace pcl
55 {
65  template <typename PointInT, typename PointOutT>
66  class MovingLeastSquares: public CloudSurfaceProcessing<PointInT, PointOutT>
67  {
68  public:
74 
79 
83 
87 
88  typedef boost::function<int (int, double, std::vector<int> &, std::vector<float> &)> SearchMethod;
89 
91 
93  MovingLeastSquares () : CloudSurfaceProcessing<PointInT, PointOutT> (),
94  normals_ (),
95  search_method_ (),
96  tree_ (),
97  order_ (2),
98  polynomial_fit_ (true),
99  search_radius_ (0.0),
100  sqr_gauss_param_ (0.0),
101  compute_normals_ (false),
102  upsample_method_ (NONE),
103  upsampling_radius_ (0.0),
104  upsampling_step_ (0.0),
105  rng_uniform_distribution_ (),
106  desired_num_points_in_radius_ (0),
107  mls_results_ (),
108  voxel_size_ (1.0),
109  dilation_iteration_num_ (0),
110  nr_coeff_ ()
111  {};
112 
113 
117  inline void
118  setComputeNormals (bool compute_normals) { compute_normals_ = compute_normals; }
119 
123  inline void
125  {
126  tree_ = tree;
127  // Declare the search locator definition
128  int (KdTree::*radiusSearch)(int index, double radius, std::vector<int> &k_indices, std::vector<float> &k_sqr_distances, unsigned int max_nn) const = &KdTree::radiusSearch;
129  search_method_ = boost::bind (radiusSearch, boost::ref (tree_), _1, _2, _3, _4, 0);
130  }
131 
133  inline KdTreePtr
134  getSearchMethod () { return (tree_); }
135 
139  inline void
140  setPolynomialOrder (int order) { order_ = order; }
141 
143  inline int
144  getPolynomialOrder () { return (order_); }
145 
149  inline void
150  setPolynomialFit (bool polynomial_fit) { polynomial_fit_ = polynomial_fit; }
151 
153  inline bool
154  getPolynomialFit () { return (polynomial_fit_); }
155 
160  inline void
161  setSearchRadius (double radius) { search_radius_ = radius; sqr_gauss_param_ = search_radius_ * search_radius_; }
162 
164  inline double
165  getSearchRadius () { return (search_radius_); }
166 
171  inline void
172  setSqrGaussParam (double sqr_gauss_param) { sqr_gauss_param_ = sqr_gauss_param; }
173 
175  inline double
176  getSqrGaussParam () const { return (sqr_gauss_param_); }
177 
194  inline void
195  setUpsamplingMethod (UpsamplingMethod method) { upsample_method_ = method; }
196 
197 
202  inline void
203  setUpsamplingRadius (double radius) { upsampling_radius_ = radius; }
204 
208  inline double
209  getUpsamplingRadius () { return upsampling_radius_; }
210 
215  inline void
216  setUpsamplingStepSize (double step_size) { upsampling_step_ = step_size; }
217 
218 
222  inline double
223  getUpsamplingStepSize () { return upsampling_step_; }
224 
230  inline void
231  setPointDensity (int desired_num_points_in_radius) { desired_num_points_in_radius_ = desired_num_points_in_radius; }
232 
233 
237  inline int
238  getPointDensity () { return desired_num_points_in_radius_; }
239 
244  inline void
245  setDilationVoxelSize (float voxel_size) { voxel_size_ = voxel_size; }
246 
247 
251  inline float
252  getDilationVoxelSize () { return voxel_size_; }
253 
258  inline void
259  setDilationIterations (int iterations) { dilation_iteration_num_ = iterations; }
260 
264  inline int
265  getDilationIterations () { return dilation_iteration_num_; }
266 
270  void
271  process (PointCloudOut &output);
272 
273  protected:
275  NormalCloudPtr normals_;
276 
278  SearchMethod search_method_;
279 
281  KdTreePtr tree_;
282 
284  int order_;
285 
287  bool polynomial_fit_;
288 
290  double search_radius_;
291 
293  double sqr_gauss_param_;
294 
296  bool compute_normals_;
297 
299  UpsamplingMethod upsample_method_;
300 
304  double upsampling_radius_;
305 
309  double upsampling_step_;
310 
314  boost::variate_generator<boost::mt19937, boost::uniform_real<float> > *rng_uniform_distribution_;
315 
319  int desired_num_points_in_radius_;
320 
321 
325  struct MLSResult
326  {
327  MLSResult () : plane_normal (), u (), v (), c_vec (), num_neighbors (), curvature (), valid (false) {}
328 
329  MLSResult (Eigen::Vector3d &a_plane_normal,
330  Eigen::Vector3d &a_u,
331  Eigen::Vector3d &a_v,
332  Eigen::VectorXd a_c_vec,
333  int a_num_neighbors,
334  float &a_curvature);
335 
336  Eigen::Vector3d plane_normal, u, v;
337  Eigen::VectorXd c_vec;
338  int num_neighbors;
339  float curvature;
340  bool valid;
341  };
342 
346  std::vector<MLSResult> mls_results_;
347 
348 
352  class MLSVoxelGrid
353  {
354  public:
355  struct Leaf { Leaf () : valid (true) {} bool valid; };
356 
357  MLSVoxelGrid (PointCloudInConstPtr& cloud,
358  IndicesPtr &indices,
359  float voxel_size);
360 
361  void
362  dilate ();
363 
364  inline void
365  getIndexIn1D (const Eigen::Vector3i &index, uint64_t &index_1d) const
366  {
367  index_1d = index[0] * data_size_ * data_size_ +
368  index[1] * data_size_ + index[2];
369  }
370 
371  inline void
372  getIndexIn3D (uint64_t index_1d, Eigen::Vector3i& index_3d) const
373  {
374  index_3d[0] = static_cast<Eigen::Vector3i::Scalar> (index_1d / (data_size_ * data_size_));
375  index_1d -= index_3d[0] * data_size_ * data_size_;
376  index_3d[1] = static_cast<Eigen::Vector3i::Scalar> (index_1d / data_size_);
377  index_1d -= index_3d[1] * data_size_;
378  index_3d[2] = static_cast<Eigen::Vector3i::Scalar> (index_1d);
379  }
380 
381  inline void
382  getCellIndex (const Eigen::Vector3f &p, Eigen::Vector3i& index) const
383  {
384  for (int i = 0; i < 3; ++i)
385  index[i] = static_cast<Eigen::Vector3i::Scalar> ((p[i] - bounding_min_(i)) / voxel_size_);
386  }
387 
388  inline void
389  getPosition (const uint64_t &index_1d, Eigen::Vector3f &point) const
390  {
391  Eigen::Vector3i index_3d;
392  getIndexIn3D (index_1d, index_3d);
393  for (int i = 0; i < 3; ++i)
394  point[i] = static_cast<Eigen::Vector3f::Scalar> (index_3d[i]) * voxel_size_ + bounding_min_[i];
395  }
396 
397  typedef std::map<uint64_t, Leaf> HashMap;
398  HashMap voxel_grid_;
399  Eigen::Vector4f bounding_min_, bounding_max_;
400  uint64_t data_size_;
401  float voxel_size_;
402  };
403 
404 
406  float voxel_size_;
407 
409  int dilation_iteration_num_;
410 
412  int nr_coeff_;
413 
419  inline int
420  searchForNeighbors (int index, std::vector<int> &indices, std::vector<float> &sqr_distances)
421  {
422  return (search_method_ (index, search_radius_, indices, sqr_distances));
423  }
424 
435  void
436  computeMLSPointNormal (int index,
437  const PointCloudIn &input,
438  const std::vector<int> &nn_indices,
439  std::vector<float> &nn_sqr_dists,
440  PointCloudOut &projected_points,
441  NormalCloud &projected_points_normals);
442 
457  void
458  projectPointToMLSSurface (float &u_disp, float &v_disp,
459  Eigen::Vector3d &u, Eigen::Vector3d &v,
460  Eigen::Vector3d &plane_normal,
461  float &curvature,
462  Eigen::Vector3f &query_point,
463  Eigen::VectorXd &c_vec,
464  int num_neighbors,
465  PointOutT &result_point,
466  pcl::Normal &result_normal);
467 
468  private:
472  virtual void performProcessing (PointCloudOut &output);
473 
475  std::string getClassName () const { return ("MovingLeastSquares"); }
476 
477  public:
478  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
479  };
480 }
481 
482 #endif /* #ifndef PCL_MLS_H_ */