Point Cloud Library (PCL)
1.7.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2009-2011, Willow Garage, Inc. 00006 * 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 00013 * * Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * * Redistributions in binary form must reproduce the above 00016 * copyright notice, this list of conditions and the following 00017 * disclaimer in the documentation and/or other materials provided 00018 * with the distribution. 00019 * * Neither the name of Willow Garage, Inc. nor the names of its 00020 * contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00033 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 * POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 * $Id$ 00037 * 00038 */ 00039 00040 #ifndef PCL_MLS_H_ 00041 #define PCL_MLS_H_ 00042 00043 // PCL includes 00044 #include <pcl/pcl_base.h> 00045 #include <pcl/search/pcl_search.h> 00046 #include <pcl/common/common.h> 00047 00048 #include <pcl/surface/boost.h> 00049 #include <pcl/surface/eigen.h> 00050 #include <pcl/surface/processing.h> 00051 #include <map> 00052 00053 namespace pcl 00054 { 00055 /** \brief MovingLeastSquares represent an implementation of the MLS (Moving Least Squares) algorithm 00056 * for data smoothing and improved normal estimation. It also contains methods for upsampling the 00057 * resulting cloud based on the parametric fit. 00058 * Reference paper: "Computing and Rendering Point Set Surfaces" by Marc Alexa, Johannes Behr, 00059 * Daniel Cohen-Or, Shachar Fleishman, David Levin and Claudio T. Silva 00060 * www.sci.utah.edu/~shachar/Publications/crpss.pdf 00061 * \author Zoltan Csaba Marton, Radu B. Rusu, Alexandru E. Ichim, Suat Gedikli 00062 * \ingroup surface 00063 */ 00064 template <typename PointInT, typename PointOutT> 00065 class MovingLeastSquares: public CloudSurfaceProcessing<PointInT, PointOutT> 00066 { 00067 public: 00068 typedef boost::shared_ptr<MovingLeastSquares<PointInT, PointOutT> > Ptr; 00069 typedef boost::shared_ptr<const MovingLeastSquares<PointInT, PointOutT> > ConstPtr; 00070 00071 using PCLBase<PointInT>::input_; 00072 using PCLBase<PointInT>::indices_; 00073 using PCLBase<PointInT>::fake_indices_; 00074 using PCLBase<PointInT>::initCompute; 00075 using PCLBase<PointInT>::deinitCompute; 00076 00077 typedef typename pcl::search::Search<PointInT> KdTree; 00078 typedef typename pcl::search::Search<PointInT>::Ptr KdTreePtr; 00079 typedef pcl::PointCloud<pcl::Normal> NormalCloud; 00080 typedef pcl::PointCloud<pcl::Normal>::Ptr NormalCloudPtr; 00081 00082 typedef pcl::PointCloud<PointOutT> PointCloudOut; 00083 typedef typename PointCloudOut::Ptr PointCloudOutPtr; 00084 typedef typename PointCloudOut::ConstPtr PointCloudOutConstPtr; 00085 00086 typedef pcl::PointCloud<PointInT> PointCloudIn; 00087 typedef typename PointCloudIn::Ptr PointCloudInPtr; 00088 typedef typename PointCloudIn::ConstPtr PointCloudInConstPtr; 00089 00090 typedef boost::function<int (int, double, std::vector<int> &, std::vector<float> &)> SearchMethod; 00091 00092 enum UpsamplingMethod {NONE, DISTINCT_CLOUD, SAMPLE_LOCAL_PLANE, RANDOM_UNIFORM_DENSITY, VOXEL_GRID_DILATION}; 00093 00094 /** \brief Empty constructor. */ 00095 MovingLeastSquares () : CloudSurfaceProcessing<PointInT, PointOutT> (), 00096 normals_ (), 00097 distinct_cloud_ (), 00098 search_method_ (), 00099 tree_ (), 00100 order_ (2), 00101 polynomial_fit_ (true), 00102 search_radius_ (0.0), 00103 sqr_gauss_param_ (0.0), 00104 compute_normals_ (false), 00105 upsample_method_ (NONE), 00106 upsampling_radius_ (0.0), 00107 upsampling_step_ (0.0), 00108 desired_num_points_in_radius_ (0), 00109 mls_results_ (), 00110 voxel_size_ (1.0), 00111 dilation_iteration_num_ (0), 00112 nr_coeff_ (), 00113 corresponding_input_indices_ (), 00114 rng_alg_ (), 00115 rng_uniform_distribution_ () 00116 {}; 00117 00118 /** \brief Empty destructor */ 00119 virtual ~MovingLeastSquares () {} 00120 00121 00122 /** \brief Set whether the algorithm should also store the normals computed 00123 * \note This is optional, but need a proper output cloud type 00124 */ 00125 inline void 00126 setComputeNormals (bool compute_normals) { compute_normals_ = compute_normals; } 00127 00128 /** \brief Provide a pointer to the search object. 00129 * \param[in] tree a pointer to the spatial search object. 00130 */ 00131 inline void 00132 setSearchMethod (const KdTreePtr &tree) 00133 { 00134 tree_ = tree; 00135 // Declare the search locator definition 00136 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; 00137 search_method_ = boost::bind (radiusSearch, boost::ref (tree_), _1, _2, _3, _4, 0); 00138 } 00139 00140 /** \brief Get a pointer to the search method used. */ 00141 inline KdTreePtr 00142 getSearchMethod () { return (tree_); } 00143 00144 /** \brief Set the order of the polynomial to be fit. 00145 * \param[in] order the order of the polynomial 00146 */ 00147 inline void 00148 setPolynomialOrder (int order) { order_ = order; } 00149 00150 /** \brief Get the order of the polynomial to be fit. */ 00151 inline int 00152 getPolynomialOrder () { return (order_); } 00153 00154 /** \brief Sets whether the surface and normal are approximated using a polynomial, or only via tangent estimation. 00155 * \param[in] polynomial_fit set to true for polynomial fit 00156 */ 00157 inline void 00158 setPolynomialFit (bool polynomial_fit) { polynomial_fit_ = polynomial_fit; } 00159 00160 /** \brief Get the polynomial_fit value (true if the surface and normal are approximated using a polynomial). */ 00161 inline bool 00162 getPolynomialFit () { return (polynomial_fit_); } 00163 00164 /** \brief Set the sphere radius that is to be used for determining the k-nearest neighbors used for fitting. 00165 * \param[in] radius the sphere radius that is to contain all k-nearest neighbors 00166 * \note Calling this method resets the squared Gaussian parameter to radius * radius ! 00167 */ 00168 inline void 00169 setSearchRadius (double radius) { search_radius_ = radius; sqr_gauss_param_ = search_radius_ * search_radius_; } 00170 00171 /** \brief Get the sphere radius used for determining the k-nearest neighbors. */ 00172 inline double 00173 getSearchRadius () { return (search_radius_); } 00174 00175 /** \brief Set the parameter used for distance based weighting of neighbors (the square of the search radius works 00176 * best in general). 00177 * \param[in] sqr_gauss_param the squared Gaussian parameter 00178 */ 00179 inline void 00180 setSqrGaussParam (double sqr_gauss_param) { sqr_gauss_param_ = sqr_gauss_param; } 00181 00182 /** \brief Get the parameter for distance based weighting of neighbors. */ 00183 inline double 00184 getSqrGaussParam () const { return (sqr_gauss_param_); } 00185 00186 /** \brief Set the upsampling method to be used 00187 * \note Options are: * NONE - no upsampling will be done, only the input points will be projected to their own 00188 * MLS surfaces 00189 * * DISTINCT_CLOUD - will project the points of the distinct cloud to the closest point on 00190 * the MLS surface 00191 * * SAMPLE_LOCAL_PLANE - the local plane of each input point will be sampled in a circular 00192 * fashion using the \ref upsampling_radius_ and the \ref upsampling_step_ 00193 * parameters 00194 * * RANDOM_UNIFORM_DENSITY - the local plane of each input point will be sampled using an 00195 * uniform random distribution such that the density of points is 00196 * constant throughout the cloud - given by the \ref \ref desired_num_points_in_radius_ 00197 * parameter 00198 * * VOXEL_GRID_DILATION - the input cloud will be inserted into a voxel grid with voxels of 00199 * size \ref voxel_size_; this voxel grid will be dilated \ref dilation_iteration_num_ 00200 * times and the resulting points will be projected to the MLS surface 00201 * of the closest point in the input cloud; the result is a point cloud 00202 * with filled holes and a constant point density 00203 */ 00204 inline void 00205 setUpsamplingMethod (UpsamplingMethod method) { upsample_method_ = method; } 00206 00207 /** \brief Set the distinct cloud used for the DISTINCT_CLOUD upsampling method. */ 00208 inline void 00209 setDistinctCloud (PointCloudInConstPtr distinct_cloud) { distinct_cloud_ = distinct_cloud; } 00210 00211 /** \brief Get the distinct cloud used for the DISTINCT_CLOUD upsampling method. */ 00212 inline PointCloudInConstPtr 00213 getDistinctCloud () { return distinct_cloud_; } 00214 00215 00216 /** \brief Set the radius of the circle in the local point plane that will be sampled 00217 * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling 00218 * \param[in] radius the radius of the circle 00219 */ 00220 inline void 00221 setUpsamplingRadius (double radius) { upsampling_radius_ = radius; } 00222 00223 /** \brief Get the radius of the circle in the local point plane that will be sampled 00224 * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling 00225 */ 00226 inline double 00227 getUpsamplingRadius () { return upsampling_radius_; } 00228 00229 /** \brief Set the step size for the local plane sampling 00230 * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling 00231 * \param[in] step_size the step size 00232 */ 00233 inline void 00234 setUpsamplingStepSize (double step_size) { upsampling_step_ = step_size; } 00235 00236 00237 /** \brief Get the step size for the local plane sampling 00238 * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling 00239 */ 00240 inline double 00241 getUpsamplingStepSize () { return upsampling_step_; } 00242 00243 /** \brief Set the parameter that specifies the desired number of points within the search radius 00244 * \note Used only in the case of RANDOM_UNIFORM_DENSITY upsampling 00245 * \param[in] desired_num_points_in_radius the desired number of points in the output cloud in a sphere of 00246 * radius \ref search_radius_ around each point 00247 */ 00248 inline void 00249 setPointDensity (int desired_num_points_in_radius) { desired_num_points_in_radius_ = desired_num_points_in_radius; } 00250 00251 00252 /** \brief Get the parameter that specifies the desired number of points within the search radius 00253 * \note Used only in the case of RANDOM_UNIFORM_DENSITY upsampling 00254 */ 00255 inline int 00256 getPointDensity () { return desired_num_points_in_radius_; } 00257 00258 /** \brief Set the voxel size for the voxel grid 00259 * \note Used only in the VOXEL_GRID_DILATION upsampling method 00260 * \param[in] voxel_size the edge length of a cubic voxel in the voxel grid 00261 */ 00262 inline void 00263 setDilationVoxelSize (float voxel_size) { voxel_size_ = voxel_size; } 00264 00265 00266 /** \brief Get the voxel size for the voxel grid 00267 * \note Used only in the VOXEL_GRID_DILATION upsampling method 00268 */ 00269 inline float 00270 getDilationVoxelSize () { return voxel_size_; } 00271 00272 /** \brief Set the number of dilation steps of the voxel grid 00273 * \note Used only in the VOXEL_GRID_DILATION upsampling method 00274 * \param[in] iterations the number of dilation iterations 00275 */ 00276 inline void 00277 setDilationIterations (int iterations) { dilation_iteration_num_ = iterations; } 00278 00279 /** \brief Get the number of dilation steps of the voxel grid 00280 * \note Used only in the VOXEL_GRID_DILATION upsampling method 00281 */ 00282 inline int 00283 getDilationIterations () { return dilation_iteration_num_; } 00284 00285 /** \brief Base method for surface reconstruction for all points given in <setInputCloud (), setIndices ()> 00286 * \param[out] output the resultant reconstructed surface model 00287 */ 00288 void 00289 process (PointCloudOut &output); 00290 00291 00292 /** \brief Get the set of indices with each point in output having the 00293 * corresponding point in input */ 00294 inline PointIndicesPtr 00295 getCorrespondingIndices () { return (corresponding_input_indices_); } 00296 00297 protected: 00298 /** \brief The point cloud that will hold the estimated normals, if set. */ 00299 NormalCloudPtr normals_; 00300 00301 /** \brief The distinct point cloud that will be projected to the MLS surface. */ 00302 PointCloudInConstPtr distinct_cloud_; 00303 00304 /** \brief The search method template for indices. */ 00305 SearchMethod search_method_; 00306 00307 /** \brief A pointer to the spatial search object. */ 00308 KdTreePtr tree_; 00309 00310 /** \brief The order of the polynomial to be fit. */ 00311 int order_; 00312 00313 /** True if the surface and normal be approximated using a polynomial, false if tangent estimation is sufficient. */ 00314 bool polynomial_fit_; 00315 00316 /** \brief The nearest neighbors search radius for each point. */ 00317 double search_radius_; 00318 00319 /** \brief Parameter for distance based weighting of neighbors (search_radius_ * search_radius_ works fine) */ 00320 double sqr_gauss_param_; 00321 00322 /** \brief Parameter that specifies whether the normals should be computed for the input cloud or not */ 00323 bool compute_normals_; 00324 00325 /** \brief Parameter that specifies the upsampling method to be used */ 00326 UpsamplingMethod upsample_method_; 00327 00328 /** \brief Radius of the circle in the local point plane that will be sampled 00329 * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling 00330 */ 00331 double upsampling_radius_; 00332 00333 /** \brief Step size for the local plane sampling 00334 * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling 00335 */ 00336 double upsampling_step_; 00337 00338 /** \brief Parameter that specifies the desired number of points within the search radius 00339 * \note Used only in the case of RANDOM_UNIFORM_DENSITY upsampling 00340 */ 00341 int desired_num_points_in_radius_; 00342 00343 00344 /** \brief Data structure used to store the results of the MLS fitting 00345 * \note Used only in the case of VOXEL_GRID_DILATION or DISTINCT_CLOUD upsampling 00346 */ 00347 struct MLSResult 00348 { 00349 MLSResult () : mean (), plane_normal (), u_axis (), v_axis (), c_vec (), num_neighbors (), curvature (), valid (false) {} 00350 00351 MLSResult (const Eigen::Vector3d &a_mean, 00352 const Eigen::Vector3d &a_plane_normal, 00353 const Eigen::Vector3d &a_u, 00354 const Eigen::Vector3d &a_v, 00355 const Eigen::VectorXd a_c_vec, 00356 const int a_num_neighbors, 00357 const float &a_curvature); 00358 00359 Eigen::Vector3d mean, plane_normal, u_axis, v_axis; 00360 Eigen::VectorXd c_vec; 00361 int num_neighbors; 00362 float curvature; 00363 bool valid; 00364 }; 00365 00366 /** \brief Stores the MLS result for each point in the input cloud 00367 * \note Used only in the case of VOXEL_GRID_DILATION or DISTINCT_CLOUD upsampling 00368 */ 00369 std::vector<MLSResult> mls_results_; 00370 00371 00372 /** \brief A minimalistic implementation of a voxel grid, necessary for the point cloud upsampling 00373 * \note Used only in the case of VOXEL_GRID_DILATION upsampling 00374 */ 00375 class MLSVoxelGrid 00376 { 00377 public: 00378 struct Leaf { Leaf () : valid (true) {} bool valid; }; 00379 00380 MLSVoxelGrid (PointCloudInConstPtr& cloud, 00381 IndicesPtr &indices, 00382 float voxel_size); 00383 00384 void 00385 dilate (); 00386 00387 inline void 00388 getIndexIn1D (const Eigen::Vector3i &index, uint64_t &index_1d) const 00389 { 00390 index_1d = index[0] * data_size_ * data_size_ + 00391 index[1] * data_size_ + index[2]; 00392 } 00393 00394 inline void 00395 getIndexIn3D (uint64_t index_1d, Eigen::Vector3i& index_3d) const 00396 { 00397 index_3d[0] = static_cast<Eigen::Vector3i::Scalar> (index_1d / (data_size_ * data_size_)); 00398 index_1d -= index_3d[0] * data_size_ * data_size_; 00399 index_3d[1] = static_cast<Eigen::Vector3i::Scalar> (index_1d / data_size_); 00400 index_1d -= index_3d[1] * data_size_; 00401 index_3d[2] = static_cast<Eigen::Vector3i::Scalar> (index_1d); 00402 } 00403 00404 inline void 00405 getCellIndex (const Eigen::Vector3f &p, Eigen::Vector3i& index) const 00406 { 00407 for (int i = 0; i < 3; ++i) 00408 index[i] = static_cast<Eigen::Vector3i::Scalar> ((p[i] - bounding_min_(i)) / voxel_size_); 00409 } 00410 00411 inline void 00412 getPosition (const uint64_t &index_1d, Eigen::Vector3f &point) const 00413 { 00414 Eigen::Vector3i index_3d; 00415 getIndexIn3D (index_1d, index_3d); 00416 for (int i = 0; i < 3; ++i) 00417 point[i] = static_cast<Eigen::Vector3f::Scalar> (index_3d[i]) * voxel_size_ + bounding_min_[i]; 00418 } 00419 00420 typedef std::map<uint64_t, Leaf> HashMap; 00421 HashMap voxel_grid_; 00422 Eigen::Vector4f bounding_min_, bounding_max_; 00423 uint64_t data_size_; 00424 float voxel_size_; 00425 }; 00426 00427 00428 /** \brief Voxel size for the VOXEL_GRID_DILATION upsampling method */ 00429 float voxel_size_; 00430 00431 /** \brief Number of dilation steps for the VOXEL_GRID_DILATION upsampling method */ 00432 int dilation_iteration_num_; 00433 00434 /** \brief Number of coefficients, to be computed from the requested order.*/ 00435 int nr_coeff_; 00436 00437 /** \brief Collects for each point in output the corrseponding point in the input. */ 00438 PointIndicesPtr corresponding_input_indices_; 00439 00440 /** \brief Search for the closest nearest neighbors of a given point using a radius search 00441 * \param[in] index the index of the query point 00442 * \param[out] indices the resultant vector of indices representing the k-nearest neighbors 00443 * \param[out] sqr_distances the resultant squared distances from the query point to the k-nearest neighbors 00444 */ 00445 inline int 00446 searchForNeighbors (int index, std::vector<int> &indices, std::vector<float> &sqr_distances) const 00447 { 00448 return (search_method_ (index, search_radius_, indices, sqr_distances)); 00449 } 00450 00451 /** \brief Smooth a given point and its neighborghood using Moving Least Squares. 00452 * \param[in] index the inex of the query point in the \ref input cloud 00453 * \param[in] nn_indices the set of nearest neighbors indices for \ref pt 00454 * \param[in] nn_sqr_dists the set of nearest neighbors squared distances for \ref pt 00455 * \param[out] projected_points the set of points projected points around the query point 00456 * (in the case of upsampling method NONE, only the query point projected to its own fitted surface will be returned, 00457 * in the case of the other upsampling methods, multiple points will be returned) 00458 * \param[out] projected_points_normals the normals corresponding to the projected points 00459 * \param[out] corresponding_input_indices the set of indices with each point in output having the corresponding point in input 00460 * \param[out] mls_result stores the MLS result for each point in the input cloud 00461 * (used only in the case of VOXEL_GRID_DILATION or DISTINCT_CLOUD upsampling) 00462 */ 00463 void 00464 computeMLSPointNormal (int index, 00465 const std::vector<int> &nn_indices, 00466 std::vector<float> &nn_sqr_dists, 00467 PointCloudOut &projected_points, 00468 NormalCloud &projected_points_normals, 00469 PointIndices &corresponding_input_indices, 00470 MLSResult &mls_result) const; 00471 00472 /** \brief Fits a point (sample point) given in the local plane coordinates of an input point (query point) to 00473 * the MLS surface of the input point 00474 * \param[in] u_disp the u coordinate of the sample point in the local plane of the query point 00475 * \param[in] v_disp the v coordinate of the sample point in the local plane of the query point 00476 * \param[in] u the axis corresponding to the u-coordinates of the local plane of the query point 00477 * \param[in] v the axis corresponding to the v-coordinates of the local plane of the query point 00478 * \param[in] plane_normal the normal to the local plane of the query point 00479 * \param[in] curvature the curvature of the surface at the query point 00480 * \param[in] query_point the absolute 3D position of the query point 00481 * \param[in] c_vec the coefficients of the polynomial fit on the MLS surface of the query point 00482 * \param[in] num_neighbors the number of neighbors of the query point in the input cloud 00483 * \param[out] result_point the absolute 3D position of the resulting projected point 00484 * \param[out] result_normal the normal of the resulting projected point 00485 */ 00486 void 00487 projectPointToMLSSurface (float &u_disp, float &v_disp, 00488 Eigen::Vector3d &u_axis, Eigen::Vector3d &v_axis, 00489 Eigen::Vector3d &n_axis, 00490 Eigen::Vector3d &mean, 00491 float &curvature, 00492 Eigen::VectorXd &c_vec, 00493 int num_neighbors, 00494 PointOutT &result_point, 00495 pcl::Normal &result_normal) const; 00496 00497 void 00498 copyMissingFields (const PointInT &point_in, 00499 PointOutT &point_out) const; 00500 00501 /** \brief Abstract surface reconstruction method. 00502 * \param[out] output the result of the reconstruction 00503 */ 00504 virtual void performProcessing (PointCloudOut &output); 00505 00506 /** \brief Perform upsampling for the distinct-cloud and voxel-grid methods 00507 * \param[out] output the result of the reconstruction 00508 */ 00509 void performUpsampling (PointCloudOut &output); 00510 00511 private: 00512 /** \brief Boost-based random number generator algorithm. */ 00513 boost::mt19937 rng_alg_; 00514 00515 /** \brief Random number generator using an uniform distribution of floats 00516 * \note Used only in the case of RANDOM_UNIFORM_DENSITY upsampling 00517 */ 00518 boost::shared_ptr<boost::variate_generator<boost::mt19937&, 00519 boost::uniform_real<float> > 00520 > rng_uniform_distribution_; 00521 00522 /** \brief Abstract class get name method. */ 00523 std::string getClassName () const { return ("MovingLeastSquares"); } 00524 00525 public: 00526 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00527 }; 00528 00529 #ifdef _OPENMP 00530 /** \brief MovingLeastSquaresOMP is a parallelized version of MovingLeastSquares, using the OpenMP standard. 00531 * \note Compared to MovingLeastSquares, an overhead is incurred in terms of runtime and memory usage. 00532 * \note The upsampling methods DISTINCT_CLOUD and VOXEL_GRID_DILATION are not parallelized completely, i.e. parts of the algorithm run on a single thread only. 00533 * \author Robert Huitl 00534 * \ingroup surface 00535 */ 00536 template <typename PointInT, typename PointOutT> 00537 class MovingLeastSquaresOMP: public MovingLeastSquares<PointInT, PointOutT> 00538 { 00539 public: 00540 typedef boost::shared_ptr<MovingLeastSquares<PointInT, PointOutT> > Ptr; 00541 typedef boost::shared_ptr<const MovingLeastSquares<PointInT, PointOutT> > ConstPtr; 00542 00543 using PCLBase<PointInT>::input_; 00544 using PCLBase<PointInT>::indices_; 00545 using MovingLeastSquares<PointInT, PointOutT>::normals_; 00546 using MovingLeastSquares<PointInT, PointOutT>::corresponding_input_indices_; 00547 using MovingLeastSquares<PointInT, PointOutT>::nr_coeff_; 00548 using MovingLeastSquares<PointInT, PointOutT>::order_; 00549 using MovingLeastSquares<PointInT, PointOutT>::compute_normals_; 00550 00551 typedef pcl::PointCloud<pcl::Normal> NormalCloud; 00552 typedef pcl::PointCloud<pcl::Normal>::Ptr NormalCloudPtr; 00553 00554 typedef pcl::PointCloud<PointOutT> PointCloudOut; 00555 typedef typename PointCloudOut::Ptr PointCloudOutPtr; 00556 typedef typename PointCloudOut::ConstPtr PointCloudOutConstPtr; 00557 00558 /** \brief Constructor for parallelized Moving Least Squares 00559 * \param threads the maximum number of hardware threads to use (0 sets the value to 1) 00560 */ 00561 MovingLeastSquaresOMP (unsigned int threads = 0) : threads_ (threads) 00562 { 00563 00564 } 00565 00566 /** \brief Set the maximum number of threads to use 00567 * \param threads the maximum number of hardware threads to use (0 sets the value to 1) 00568 */ 00569 inline void 00570 setNumberOfThreads (unsigned int threads = 0) 00571 { 00572 threads_ = threads; 00573 } 00574 00575 protected: 00576 /** \brief Abstract surface reconstruction method. 00577 * \param[out] output the result of the reconstruction 00578 */ 00579 virtual void performProcessing (PointCloudOut &output); 00580 00581 /** \brief The maximum number of threads the scheduler should use. */ 00582 unsigned int threads_; 00583 }; 00584 #endif 00585 } 00586 00587 #ifdef PCL_NO_PRECOMPILE 00588 #include <pcl/surface/impl/mls.hpp> 00589 #endif 00590 00591 #endif /* #ifndef PCL_MLS_H_ */