Point Cloud Library (PCL)  1.14.0-dev
voxel_grid.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 #pragma once
41 
42 #include <pcl/filters/filter.h>
43 #include <limits>
44 
45 namespace pcl
46 {
47  /** \brief Obtain the maximum and minimum points in 3D from a given point cloud.
48  * \param[in] cloud the pointer to a pcl::PCLPointCloud2 dataset
49  * \param[in] x_idx the index of the X channel
50  * \param[in] y_idx the index of the Y channel
51  * \param[in] z_idx the index of the Z channel
52  * \param[out] min_pt the minimum data point
53  * \param[out] max_pt the maximum data point
54  */
55  PCL_EXPORTS void
56  getMinMax3D (const pcl::PCLPointCloud2ConstPtr &cloud, int x_idx, int y_idx, int z_idx,
57  Eigen::Vector4f &min_pt, Eigen::Vector4f &max_pt);
58 
59  /** \brief Obtain the maximum and minimum points in 3D from a given point cloud.
60  * \note Performs internal data filtering as well.
61  * \param[in] cloud the pointer to a pcl::PCLPointCloud2 dataset
62  * \param[in] x_idx the index of the X channel
63  * \param[in] y_idx the index of the Y channel
64  * \param[in] z_idx the index of the Z channel
65  * \param[in] distance_field_name the name of the dimension to filter data along to
66  * \param[in] min_distance the minimum acceptable value in \a distance_field_name data
67  * \param[in] max_distance the maximum acceptable value in \a distance_field_name data
68  * \param[out] min_pt the minimum data point
69  * \param[out] max_pt the maximum data point
70  * \param[in] limit_negative \b false if data \b inside of the [min_distance; max_distance] interval should be
71  * considered, \b true otherwise.
72  */
73  PCL_EXPORTS void
74  getMinMax3D (const pcl::PCLPointCloud2ConstPtr &cloud, int x_idx, int y_idx, int z_idx,
75  const std::string &distance_field_name, float min_distance, float max_distance,
76  Eigen::Vector4f &min_pt, Eigen::Vector4f &max_pt, bool limit_negative = false);
77 
78  /** \brief Get the relative cell indices of the "upper half" 13 neighbors.
79  * \note Useful in combination with getNeighborCentroidIndices() from \ref VoxelGrid
80  * \ingroup filters
81  */
82  inline Eigen::MatrixXi
84  {
85  Eigen::MatrixXi relative_coordinates (3, 13);
86  int idx = 0;
87 
88  // 0 - 8
89  for (int i = -1; i < 2; i++)
90  {
91  for (int j = -1; j < 2; j++)
92  {
93  relative_coordinates (0, idx) = i;
94  relative_coordinates (1, idx) = j;
95  relative_coordinates (2, idx) = -1;
96  idx++;
97  }
98  }
99  // 9 - 11
100  for (int i = -1; i < 2; i++)
101  {
102  relative_coordinates (0, idx) = i;
103  relative_coordinates (1, idx) = -1;
104  relative_coordinates (2, idx) = 0;
105  idx++;
106  }
107  // 12
108  relative_coordinates (0, idx) = -1;
109  relative_coordinates (1, idx) = 0;
110  relative_coordinates (2, idx) = 0;
111 
112  return (relative_coordinates);
113  }
114 
115  /** \brief Get the relative cell indices of all the 26 neighbors.
116  * \note Useful in combination with getNeighborCentroidIndices() from \ref VoxelGrid
117  * \ingroup filters
118  */
119  inline Eigen::MatrixXi
121  {
122  Eigen::MatrixXi relative_coordinates = getHalfNeighborCellIndices ();
123  Eigen::MatrixXi relative_coordinates_all( 3, 26);
124  relative_coordinates_all.block<3, 13> (0, 0) = relative_coordinates;
125  relative_coordinates_all.block<3, 13> (0, 13) = -relative_coordinates;
126  return (relative_coordinates_all);
127  }
128 
129  /** \brief Get the minimum and maximum values on each of the 3 (x-y-z) dimensions
130  * in a given pointcloud, without considering points outside of a distance threshold from the laser origin
131  * \param[in] cloud the point cloud data message
132  * \param[in] distance_field_name the field name that contains the distance values
133  * \param[in] min_distance the minimum distance a point will be considered from
134  * \param[in] max_distance the maximum distance a point will be considered to
135  * \param[out] min_pt the resultant minimum bounds
136  * \param[out] max_pt the resultant maximum bounds
137  * \param[in] limit_negative if set to true, then all points outside of the interval (min_distance;max_distace) are considered
138  * \ingroup filters
139  */
140  template <typename PointT> void
141  getMinMax3D (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
142  const std::string &distance_field_name, float min_distance, float max_distance,
143  Eigen::Vector4f &min_pt, Eigen::Vector4f &max_pt, bool limit_negative = false);
144 
145  /** \brief Get the minimum and maximum values on each of the 3 (x-y-z) dimensions
146  * in a given pointcloud, without considering points outside of a distance threshold from the laser origin
147  * \param[in] cloud the point cloud data message
148  * \param[in] indices the vector of indices to use
149  * \param[in] distance_field_name the field name that contains the distance values
150  * \param[in] min_distance the minimum distance a point will be considered from
151  * \param[in] max_distance the maximum distance a point will be considered to
152  * \param[out] min_pt the resultant minimum bounds
153  * \param[out] max_pt the resultant maximum bounds
154  * \param[in] limit_negative if set to true, then all points outside of the interval (min_distance;max_distace) are considered
155  * \ingroup filters
156  */
157  template <typename PointT> void
158  getMinMax3D (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
159  const Indices &indices,
160  const std::string &distance_field_name, float min_distance, float max_distance,
161  Eigen::Vector4f &min_pt, Eigen::Vector4f &max_pt, bool limit_negative = false);
162 
163  /** \brief VoxelGrid assembles a local 3D grid over a given PointCloud, and downsamples + filters the data.
164  *
165  * The VoxelGrid class creates a *3D voxel grid* (think about a voxel
166  * grid as a set of tiny 3D boxes in space) over the input point cloud data.
167  * Then, in each *voxel* (i.e., 3D box), all the points present will be
168  * approximated (i.e., *downsampled*) with their centroid. This approach is
169  * a bit slower than approximating them with the center of the voxel, but it
170  * represents the underlying surface more accurately.
171  *
172  * \author Radu B. Rusu, Bastian Steder
173  * \ingroup filters
174  */
175  template <typename PointT>
176  class VoxelGrid: public Filter<PointT>
177  {
178  protected:
183 
185  using PointCloudPtr = typename PointCloud::Ptr;
187 
188  public:
189 
190  using Ptr = shared_ptr<VoxelGrid<PointT> >;
191  using ConstPtr = shared_ptr<const VoxelGrid<PointT> >;
192 
194 
195  /** \brief Empty constructor. */
197  leaf_size_ (Eigen::Vector4f::Zero ()),
198  inverse_leaf_size_ (Eigen::Array4f::Zero ()),
199  min_b_ (Eigen::Vector4i::Zero ()),
200  max_b_ (Eigen::Vector4i::Zero ()),
201  div_b_ (Eigen::Vector4i::Zero ()),
202  divb_mul_ (Eigen::Vector4i::Zero ())
203  {
204  filter_name_ = "VoxelGrid";
205  }
206 
207  /** \brief Destructor. */
208  ~VoxelGrid () override = default;
209 
210  /** \brief Set the voxel grid leaf size.
211  * \param[in] leaf_size the voxel grid leaf size
212  */
213  inline void
214  setLeafSize (const Eigen::Vector4f &leaf_size)
215  {
216  leaf_size_ = leaf_size;
217  // Avoid division errors
218  if (leaf_size_[3] == 0)
219  leaf_size_[3] = 1;
220  // Use multiplications instead of divisions
221  inverse_leaf_size_ = Eigen::Array4f::Ones () / leaf_size_.array ();
222  }
223 
224  /** \brief Set the voxel grid leaf size.
225  * \param[in] lx the leaf size for X
226  * \param[in] ly the leaf size for Y
227  * \param[in] lz the leaf size for Z
228  */
229  inline void
230  setLeafSize (float lx, float ly, float lz)
231  {
232  leaf_size_[0] = lx; leaf_size_[1] = ly; leaf_size_[2] = lz;
233  // Avoid division errors
234  if (leaf_size_[3] == 0)
235  leaf_size_[3] = 1;
236  // Use multiplications instead of divisions
237  inverse_leaf_size_ = Eigen::Array4f::Ones () / leaf_size_.array ();
238  }
239 
240  /** \brief Get the voxel grid leaf size. */
241  inline Eigen::Vector3f
242  getLeafSize () const { return (leaf_size_.head<3> ()); }
243 
244  /** \brief Set to true if all fields need to be downsampled, or false if just XYZ.
245  * \param[in] downsample the new value (true/false)
246  */
247  inline void
248  setDownsampleAllData (bool downsample) { downsample_all_data_ = downsample; }
249 
250  /** \brief Get the state of the internal downsampling parameter (true if
251  * all fields need to be downsampled, false if just XYZ).
252  */
253  inline bool
255 
256  /** \brief Set the minimum number of points required for a voxel to be used.
257  * \param[in] min_points_per_voxel the minimum number of points for required for a voxel to be used
258  */
259  inline void
260  setMinimumPointsNumberPerVoxel (unsigned int min_points_per_voxel) { min_points_per_voxel_ = min_points_per_voxel; }
261 
262  /** \brief Return the minimum number of points required for a voxel to be used.
263  */
264  inline unsigned int
266 
267  /** \brief Set to true if leaf layout information needs to be saved for later access.
268  * \param[in] save_leaf_layout the new value (true/false)
269  */
270  inline void
271  setSaveLeafLayout (bool save_leaf_layout) { save_leaf_layout_ = save_leaf_layout; }
272 
273  /** \brief Returns true if leaf layout information will to be saved for later access. */
274  inline bool
275  getSaveLeafLayout () const { return (save_leaf_layout_); }
276 
277  /** \brief Get the minimum coordinates of the bounding box (after
278  * filtering is performed).
279  */
280  inline Eigen::Vector3i
281  getMinBoxCoordinates () const { return (min_b_.head<3> ()); }
282 
283  /** \brief Get the minimum coordinates of the bounding box (after
284  * filtering is performed).
285  */
286  inline Eigen::Vector3i
287  getMaxBoxCoordinates () const { return (max_b_.head<3> ()); }
288 
289  /** \brief Get the number of divisions along all 3 axes (after filtering
290  * is performed).
291  */
292  inline Eigen::Vector3i
293  getNrDivisions () const { return (div_b_.head<3> ()); }
294 
295  /** \brief Get the multipliers to be applied to the grid coordinates in
296  * order to find the centroid index (after filtering is performed).
297  */
298  inline Eigen::Vector3i
299  getDivisionMultiplier () const { return (divb_mul_.head<3> ()); }
300 
301  /** \brief Returns the index in the resulting downsampled cloud of the specified point.
302  *
303  * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering
304  * performed, and that the point is inside the grid, to avoid invalid access (or use
305  * getGridCoordinates+getCentroidIndexAt)
306  *
307  * \param[in] p the point to get the index at
308  */
309  inline int
310  getCentroidIndex (const PointT &p) const
311  {
312  return (leaf_layout_.at ((Eigen::Vector4i (static_cast<int> (std::floor (p.x * inverse_leaf_size_[0])),
313  static_cast<int> (std::floor (p.y * inverse_leaf_size_[1])),
314  static_cast<int> (std::floor (p.z * inverse_leaf_size_[2])), 0) - min_b_).dot (divb_mul_)));
315  }
316 
317  /** \brief Returns the indices in the resulting downsampled cloud of the points at the specified grid coordinates,
318  * relative to the grid coordinates of the specified point (or -1 if the cell was empty/out of bounds).
319  * \param[in] reference_point the coordinates of the reference point (corresponding cell is allowed to be empty/out of bounds)
320  * \param[in] relative_coordinates matrix with the columns being the coordinates of the requested cells, relative to the reference point's cell
321  * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering performed
322  */
323  inline std::vector<int>
324  getNeighborCentroidIndices (const PointT &reference_point, const Eigen::MatrixXi &relative_coordinates) const
325  {
326  Eigen::Vector4i ijk (static_cast<int> (std::floor (reference_point.x * inverse_leaf_size_[0])),
327  static_cast<int> (std::floor (reference_point.y * inverse_leaf_size_[1])),
328  static_cast<int> (std::floor (reference_point.z * inverse_leaf_size_[2])), 0);
329  Eigen::Array4i diff2min = min_b_ - ijk;
330  Eigen::Array4i diff2max = max_b_ - ijk;
331  std::vector<int> neighbors (relative_coordinates.cols());
332  for (Eigen::Index ni = 0; ni < relative_coordinates.cols (); ni++)
333  {
334  Eigen::Vector4i displacement = (Eigen::Vector4i() << relative_coordinates.col(ni), 0).finished();
335  // checking if the specified cell is in the grid
336  if ((diff2min <= displacement.array()).all() && (diff2max >= displacement.array()).all())
337  neighbors[ni] = leaf_layout_[((ijk + displacement - min_b_).dot (divb_mul_))]; // .at() can be omitted
338  else
339  neighbors[ni] = -1; // cell is out of bounds, consider it empty
340  }
341  return (neighbors);
342  }
343 
344  /** \brief Returns the layout of the leafs for fast access to cells relative to current position.
345  * \note position at (i-min_x) + (j-min_y)*div_x + (k-min_z)*div_x*div_y holds the index of the element at coordinates (i,j,k) in the grid (-1 if empty)
346  */
347  inline std::vector<int>
348  getLeafLayout () const { return (leaf_layout_); }
349 
350  /** \brief Returns the corresponding (i,j,k) coordinates in the grid of point (x,y,z).
351  * \param[in] x the X point coordinate to get the (i, j, k) index at
352  * \param[in] y the Y point coordinate to get the (i, j, k) index at
353  * \param[in] z the Z point coordinate to get the (i, j, k) index at
354  */
355  inline Eigen::Vector3i
356  getGridCoordinates (float x, float y, float z) const
357  {
358  return {static_cast<int> (std::floor (x * inverse_leaf_size_[0])),
359  static_cast<int> (std::floor (y * inverse_leaf_size_[1])),
360  static_cast<int> (std::floor (z * inverse_leaf_size_[2]))};
361  }
362 
363  /** \brief Returns the index in the downsampled cloud corresponding to a given set of coordinates.
364  * \param[in] ijk the coordinates (i,j,k) in the grid (-1 if empty)
365  */
366  inline int
367  getCentroidIndexAt (const Eigen::Vector3i &ijk) const
368  {
369  int idx = ((Eigen::Vector4i() << ijk, 0).finished() - min_b_).dot (divb_mul_);
370  if (idx < 0 || idx >= static_cast<int> (leaf_layout_.size ())) // this checks also if leaf_layout_.size () == 0 i.e. everything was computed as needed
371  {
372  //if (verbose)
373  // PCL_ERROR ("[pcl::%s::getCentroidIndexAt] Specified coordinate is outside grid bounds, or leaf layout is not saved, make sure to call setSaveLeafLayout(true) and filter(output) first!\n", getClassName ().c_str ());
374  return (-1);
375  }
376  return (leaf_layout_[idx]);
377  }
378 
379  /** \brief Provide the name of the field to be used for filtering data. In conjunction with \a setFilterLimits,
380  * points having values outside this interval will be discarded.
381  * \param[in] field_name the name of the field that contains values used for filtering
382  */
383  inline void
384  setFilterFieldName (const std::string &field_name)
385  {
386  filter_field_name_ = field_name;
387  }
388 
389  /** \brief Get the name of the field used for filtering. */
390  inline std::string const
392  {
393  return (filter_field_name_);
394  }
395 
396  /** \brief Set the field filter limits. All points having field values outside this interval will be discarded.
397  * \param[in] limit_min the minimum allowed field value
398  * \param[in] limit_max the maximum allowed field value
399  */
400  inline void
401  setFilterLimits (const double &limit_min, const double &limit_max)
402  {
403  filter_limit_min_ = limit_min;
404  filter_limit_max_ = limit_max;
405  }
406 
407  /** \brief Get the field filter limits (min/max) set by the user.
408  The default values are std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max().
409  * \param[out] limit_min the minimum allowed field value
410  * \param[out] limit_max the maximum allowed field value
411  */
412  inline void
413  getFilterLimits (double &limit_min, double &limit_max) const
414  {
415  limit_min = filter_limit_min_;
416  limit_max = filter_limit_max_;
417  }
418 
419  /** \brief Set to true if we want to return the data outside the interval specified by setFilterLimits (min, max).
420  * Default: false.
421  * \param[in] limit_negative return data inside the interval (false) or outside (true)
422  */
423  inline void
424  setFilterLimitsNegative (const bool limit_negative)
425  {
426  filter_limit_negative_ = limit_negative;
427  }
428 
429  /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
430  * \param[out] limit_negative true if data \b outside the interval [min; max] is to be returned, false otherwise
431  */
432  PCL_DEPRECATED(1, 16, "use bool getFilterLimitsNegative() instead")
433  inline void
434  getFilterLimitsNegative (bool &limit_negative) const
435  {
436  limit_negative = filter_limit_negative_;
437  }
438 
439  /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
440  * \return true if data \b outside the interval [min; max] is to be returned, false otherwise
441  */
442  inline bool
444  {
445  return (filter_limit_negative_);
446  }
447 
448  protected:
449  /** \brief The size of a leaf. */
450  Eigen::Vector4f leaf_size_;
451 
452  /** \brief Internal leaf sizes stored as 1/leaf_size_ for efficiency reasons. */
453  Eigen::Array4f inverse_leaf_size_;
454 
455  /** \brief Set to true if all fields need to be downsampled, or false if just XYZ. */
457 
458  /** \brief Set to true if leaf layout information needs to be saved in \a leaf_layout_. */
459  bool save_leaf_layout_{false};
460 
461  /** \brief The leaf layout information for fast access to cells relative to current position **/
462  std::vector<int> leaf_layout_;
463 
464  /** \brief The minimum and maximum bin coordinates, the number of divisions, and the division multiplier. */
465  Eigen::Vector4i min_b_, max_b_, div_b_, divb_mul_;
466 
467  /** \brief The desired user filter field name. */
468  std::string filter_field_name_;
469 
470  /** \brief The minimum allowed filter value a point will be considered from. */
471  double filter_limit_min_{std::numeric_limits<float>::lowest()};
472 
473  /** \brief The maximum allowed filter value a point will be considered from. */
474  double filter_limit_max_{std::numeric_limits<float>::max()};
475 
476  /** \brief Set to true if we want to return the data outside (\a filter_limit_min_;\a filter_limit_max_). Default: false. */
478 
479  /** \brief Minimum number of points per voxel for the centroid to be computed */
480  unsigned int min_points_per_voxel_{0};
481 
482  using FieldList = typename pcl::traits::fieldList<PointT>::type;
483 
484  /** \brief Downsample a Point Cloud using a voxelized grid approach
485  * \param[out] output the resultant point cloud message
486  */
487  void
488  applyFilter (PointCloud &output) override;
489  };
490 
491  /** \brief VoxelGrid assembles a local 3D grid over a given PointCloud, and downsamples + filters the data.
492  *
493  * The VoxelGrid class creates a *3D voxel grid* (think about a voxel
494  * grid as a set of tiny 3D boxes in space) over the input point cloud data.
495  * Then, in each *voxel* (i.e., 3D box), all the points present will be
496  * approximated (i.e., *downsampled*) with their centroid. This approach is
497  * a bit slower than approximating them with the center of the voxel, but it
498  * represents the underlying surface more accurately.
499  *
500  * \author Radu B. Rusu, Bastian Steder, Radoslaw Cybulski
501  * \ingroup filters
502  */
503  template <>
504  class PCL_EXPORTS VoxelGrid<pcl::PCLPointCloud2> : public Filter<pcl::PCLPointCloud2>
505  {
508 
512 
513  public:
514  /** \brief Empty constructor. */
516  leaf_size_ (Eigen::Vector4f::Zero ()),
517  inverse_leaf_size_ (Eigen::Array4f::Zero ()),
518 
519  min_b_ (Eigen::Vector4i::Zero ()),
520  max_b_ (Eigen::Vector4i::Zero ()),
521  div_b_ (Eigen::Vector4i::Zero ()),
522  divb_mul_ (Eigen::Vector4i::Zero ())
523  {
524  filter_name_ = "VoxelGrid";
525  }
526 
527  /** \brief Destructor. */
528  ~VoxelGrid () override = default;
529 
530  /** \brief Set the voxel grid leaf size.
531  * \param[in] leaf_size the voxel grid leaf size
532  */
533  inline void
534  setLeafSize (const Eigen::Vector4f &leaf_size)
535  {
536  leaf_size_ = leaf_size;
537  // Avoid division errors
538  if (leaf_size_[3] == 0)
539  leaf_size_[3] = 1;
540  // Use multiplications instead of divisions
541  inverse_leaf_size_ = Eigen::Array4f::Ones () / leaf_size_.array ();
542  }
543 
544  /** \brief Set the voxel grid leaf size.
545  * \param[in] lx the leaf size for X
546  * \param[in] ly the leaf size for Y
547  * \param[in] lz the leaf size for Z
548  */
549  inline void
550  setLeafSize (float lx, float ly, float lz)
551  {
552  leaf_size_[0] = lx; leaf_size_[1] = ly; leaf_size_[2] = lz;
553  // Avoid division errors
554  if (leaf_size_[3] == 0)
555  leaf_size_[3] = 1;
556  // Use multiplications instead of divisions
557  inverse_leaf_size_ = Eigen::Array4f::Ones () / leaf_size_.array ();
558  }
559 
560  /** \brief Get the voxel grid leaf size. */
561  inline Eigen::Vector3f
562  getLeafSize () const { return (leaf_size_.head<3> ()); }
563 
564  /** \brief Set to true if all fields need to be downsampled, or false if just XYZ.
565  * \param[in] downsample the new value (true/false)
566  */
567  inline void
568  setDownsampleAllData (bool downsample) { downsample_all_data_ = downsample; }
569 
570  /** \brief Get the state of the internal downsampling parameter (true if
571  * all fields need to be downsampled, false if just XYZ).
572  */
573  inline bool
574  getDownsampleAllData () const { return (downsample_all_data_); }
575 
576  /** \brief Set the minimum number of points required for a voxel to be used.
577  * \param[in] min_points_per_voxel the minimum number of points for required for a voxel to be used
578  */
579  inline void
580  setMinimumPointsNumberPerVoxel (unsigned int min_points_per_voxel) { min_points_per_voxel_ = min_points_per_voxel; }
581 
582  /** \brief Return the minimum number of points required for a voxel to be used.
583  */
584  inline unsigned int
585  getMinimumPointsNumberPerVoxel () const { return min_points_per_voxel_; }
586 
587  /** \brief Set to true if leaf layout information needs to be saved for later access.
588  * \param[in] save_leaf_layout the new value (true/false)
589  */
590  inline void
591  setSaveLeafLayout (bool save_leaf_layout) { save_leaf_layout_ = save_leaf_layout; }
592 
593  /** \brief Returns true if leaf layout information will to be saved for later access. */
594  inline bool
595  getSaveLeafLayout () const { return (save_leaf_layout_); }
596 
597  /** \brief Get the minimum coordinates of the bounding box (after
598  * filtering is performed).
599  */
600  inline Eigen::Vector3i
601  getMinBoxCoordinates () const { return (min_b_.head<3> ()); }
602 
603  /** \brief Get the minimum coordinates of the bounding box (after
604  * filtering is performed).
605  */
606  inline Eigen::Vector3i
607  getMaxBoxCoordinates () const { return (max_b_.head<3> ()); }
608 
609  /** \brief Get the number of divisions along all 3 axes (after filtering
610  * is performed).
611  */
612  inline Eigen::Vector3i
613  getNrDivisions () const { return (div_b_.head<3> ()); }
614 
615  /** \brief Get the multipliers to be applied to the grid coordinates in
616  * order to find the centroid index (after filtering is performed).
617  */
618  inline Eigen::Vector3i
619  getDivisionMultiplier () const { return (divb_mul_.head<3> ()); }
620 
621  /** \brief Returns the index in the resulting downsampled cloud of the specified point.
622  * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering performed,
623  * and that the point is inside the grid, to avoid invalid access (or use getGridCoordinates+getCentroidIndexAt)
624  * \param[in] x the X point coordinate to get the index at
625  * \param[in] y the Y point coordinate to get the index at
626  * \param[in] z the Z point coordinate to get the index at
627  */
628  inline int
629  getCentroidIndex (float x, float y, float z) const
630  {
631  return (leaf_layout_.at ((Eigen::Vector4i (static_cast<int> (std::floor (x * inverse_leaf_size_[0])),
632  static_cast<int> (std::floor (y * inverse_leaf_size_[1])),
633  static_cast<int> (std::floor (z * inverse_leaf_size_[2])),
634  0)
635  - min_b_).dot (divb_mul_)));
636  }
637 
638  /** \brief Returns the indices in the resulting downsampled cloud of the points at the specified grid coordinates,
639  * relative to the grid coordinates of the specified point (or -1 if the cell was empty/out of bounds).
640  * \param[in] x the X coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
641  * \param[in] y the Y coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
642  * \param[in] z the Z coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
643  * \param[out] relative_coordinates matrix with the columns being the coordinates of the requested cells, relative to the reference point's cell
644  * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering performed
645  */
646  inline std::vector<int>
647  getNeighborCentroidIndices (float x, float y, float z, const Eigen::MatrixXi &relative_coordinates) const
648  {
649  Eigen::Vector4i ijk (static_cast<int> (std::floor (x * inverse_leaf_size_[0])),
650  static_cast<int> (std::floor (y * inverse_leaf_size_[1])),
651  static_cast<int> (std::floor (z * inverse_leaf_size_[2])), 0);
652  Eigen::Array4i diff2min = min_b_ - ijk;
653  Eigen::Array4i diff2max = max_b_ - ijk;
654  std::vector<int> neighbors (relative_coordinates.cols());
655  for (Eigen::Index ni = 0; ni < relative_coordinates.cols (); ni++)
656  {
657  Eigen::Vector4i displacement = (Eigen::Vector4i() << relative_coordinates.col(ni), 0).finished();
658  // checking if the specified cell is in the grid
659  if ((diff2min <= displacement.array()).all() && (diff2max >= displacement.array()).all())
660  neighbors[ni] = leaf_layout_[((ijk + displacement - min_b_).dot (divb_mul_))]; // .at() can be omitted
661  else
662  neighbors[ni] = -1; // cell is out of bounds, consider it empty
663  }
664  return (neighbors);
665  }
666 
667  /** \brief Returns the indices in the resulting downsampled cloud of the points at the specified grid coordinates,
668  * relative to the grid coordinates of the specified point (or -1 if the cell was empty/out of bounds).
669  * \param[in] x the X coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
670  * \param[in] y the Y coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
671  * \param[in] z the Z coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
672  * \param[out] relative_coordinates vector with the elements being the coordinates of the requested cells, relative to the reference point's cell
673  * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering performed
674  */
675  inline std::vector<int>
676  getNeighborCentroidIndices (float x, float y, float z, const std::vector<Eigen::Vector3i, Eigen::aligned_allocator<Eigen::Vector3i> > &relative_coordinates) const
677  {
678  Eigen::Vector4i ijk (static_cast<int> (std::floor (x * inverse_leaf_size_[0])), static_cast<int> (std::floor (y * inverse_leaf_size_[1])), static_cast<int> (std::floor (z * inverse_leaf_size_[2])), 0);
679  std::vector<int> neighbors;
680  neighbors.reserve (relative_coordinates.size ());
681  for (const auto &relative_coordinate : relative_coordinates)
682  neighbors.push_back (leaf_layout_[(ijk + (Eigen::Vector4i() << relative_coordinate, 0).finished() - min_b_).dot (divb_mul_)]);
683  return (neighbors);
684  }
685 
686  /** \brief Returns the layout of the leafs for fast access to cells relative to current position.
687  * \note position at (i-min_x) + (j-min_y)*div_x + (k-min_z)*div_x*div_y holds the index of the element at coordinates (i,j,k) in the grid (-1 if empty)
688  */
689  inline std::vector<int>
690  getLeafLayout () const { return (leaf_layout_); }
691 
692  /** \brief Returns the corresponding (i,j,k) coordinates in the grid of point (x,y,z).
693  * \param[in] x the X point coordinate to get the (i, j, k) index at
694  * \param[in] y the Y point coordinate to get the (i, j, k) index at
695  * \param[in] z the Z point coordinate to get the (i, j, k) index at
696  */
697  inline Eigen::Vector3i
698  getGridCoordinates (float x, float y, float z) const
699  {
700  return {static_cast<int> (std::floor (x * inverse_leaf_size_[0])),
701  static_cast<int> (std::floor (y * inverse_leaf_size_[1])),
702  static_cast<int> (std::floor (z * inverse_leaf_size_[2]))};
703  }
704 
705  /** \brief Returns the index in the downsampled cloud corresponding to a given set of coordinates.
706  * \param[in] ijk the coordinates (i,j,k) in the grid (-1 if empty)
707  */
708  inline int
709  getCentroidIndexAt (const Eigen::Vector3i &ijk) const
710  {
711  int idx = ((Eigen::Vector4i() << ijk, 0).finished() - min_b_).dot (divb_mul_);
712  if (idx < 0 || idx >= static_cast<int> (leaf_layout_.size ())) // this checks also if leaf_layout_.size () == 0 i.e. everything was computed as needed
713  {
714  //if (verbose)
715  // PCL_ERROR ("[pcl::%s::getCentroidIndexAt] Specified coordinate is outside grid bounds, or leaf layout is not saved, make sure to call setSaveLeafLayout(true) and filter(output) first!\n", getClassName ().c_str ());
716  return (-1);
717  }
718  return (leaf_layout_[idx]);
719  }
720 
721  /** \brief Provide the name of the field to be used for filtering data. In conjunction with \a setFilterLimits,
722  * points having values outside this interval will be discarded.
723  * \param[in] field_name the name of the field that contains values used for filtering
724  */
725  inline void
726  setFilterFieldName (const std::string &field_name)
727  {
728  filter_field_name_ = field_name;
729  }
730 
731  /** \brief Get the name of the field used for filtering. */
732  inline std::string const
734  {
735  return (filter_field_name_);
736  }
737 
738  /** \brief Set the field filter limits. All points having field values outside this interval will be discarded.
739  * \param[in] limit_min the minimum allowed field value
740  * \param[in] limit_max the maximum allowed field value
741  */
742  inline void
743  setFilterLimits (const double &limit_min, const double &limit_max)
744  {
745  filter_limit_min_ = limit_min;
746  filter_limit_max_ = limit_max;
747  }
748 
749  /** \brief Get the field filter limits (min/max) set by the user.
750  * The default values are std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max().
751  * \param[out] limit_min the minimum allowed field value
752  * \param[out] limit_max the maximum allowed field value
753  */
754  inline void
755  getFilterLimits (double &limit_min, double &limit_max) const
756  {
757  limit_min = filter_limit_min_;
758  limit_max = filter_limit_max_;
759  }
760 
761  /** \brief Set to true if we want to return the data outside the interval specified by setFilterLimits (min, max).
762  * Default: false.
763  * \param[in] limit_negative return data inside the interval (false) or outside (true)
764  */
765  inline void
766  setFilterLimitsNegative (const bool limit_negative)
767  {
768  filter_limit_negative_ = limit_negative;
769  }
770 
771  /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
772  * \param[out] limit_negative true if data \b outside the interval [min; max] is to be returned, false otherwise
773  */
774  PCL_DEPRECATED(1, 16, "use bool getFilterLimitsNegative() instead")
775  inline void
776  getFilterLimitsNegative (bool &limit_negative) const
777  {
778  limit_negative = filter_limit_negative_;
779  }
780 
781  /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
782  * \return true if data \b outside the interval [min; max] is to be returned, false otherwise
783  */
784  inline bool
786  {
787  return (filter_limit_negative_);
788  }
789 
790  protected:
791  /** \brief The size of a leaf. */
792  Eigen::Vector4f leaf_size_;
793 
794  /** \brief Internal leaf sizes stored as 1/leaf_size_ for efficiency reasons. */
795  Eigen::Array4f inverse_leaf_size_;
796 
797  /** \brief Set to true if all fields need to be downsampled, or false if just XYZ. */
798  bool downsample_all_data_{true};
799 
800  /** \brief Set to true if leaf layout information needs to be saved in \a
801  * leaf_layout.
802  */
803  bool save_leaf_layout_{false};
804 
805  /** \brief The leaf layout information for fast access to cells relative
806  * to current position
807  */
808  std::vector<int> leaf_layout_;
809 
810  /** \brief The minimum and maximum bin coordinates, the number of
811  * divisions, and the division multiplier.
812  */
813  Eigen::Vector4i min_b_, max_b_, div_b_, divb_mul_;
814 
815  /** \brief The desired user filter field name. */
816  std::string filter_field_name_;
817 
818  /** \brief The minimum allowed filter value a point will be considered from. */
819  double filter_limit_min_{std::numeric_limits<float>::lowest()};
820 
821  /** \brief The maximum allowed filter value a point will be considered from. */
822  double filter_limit_max_{std::numeric_limits<float>::max()};
823 
824  /** \brief Set to true if we want to return the data outside (\a filter_limit_min_;\a filter_limit_max_). Default: false. */
825  bool filter_limit_negative_{false};
826 
827  /** \brief Minimum number of points per voxel for the centroid to be computed */
828  unsigned int min_points_per_voxel_{0};
829 
830  /** \brief Downsample a Point Cloud using a voxelized grid approach
831  * \param[out] output the resultant point cloud
832  */
833  void
834  applyFilter (PCLPointCloud2 &output) override;
835  };
836 }
837 
838 #ifdef PCL_NO_PRECOMPILE
839 #include <pcl/filters/impl/voxel_grid.hpp>
840 #endif
Filter represents the base filter class.
Definition: filter.h:81
shared_ptr< Filter< PointT > > Ptr
Definition: filter.h:83
shared_ptr< const Filter< PointT > > ConstPtr
Definition: filter.h:84
std::string filter_name_
The filter name.
Definition: filter.h:158
PCLPointCloud2::Ptr PCLPointCloud2Ptr
Definition: pcl_base.h:185
PCLPointCloud2::ConstPtr PCLPointCloud2ConstPtr
Definition: pcl_base.h:186
typename PointCloud::Ptr PointCloudPtr
Definition: pcl_base.h:73
typename PointCloud::ConstPtr PointCloudConstPtr
Definition: pcl_base.h:74
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: point_cloud.h:173
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:413
shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:414
int getCentroidIndexAt(const Eigen::Vector3i &ijk) const
Returns the index in the downsampled cloud corresponding to a given set of coordinates.
Definition: voxel_grid.h:709
Eigen::Vector3i getDivisionMultiplier() const
Get the multipliers to be applied to the grid coordinates in order to find the centroid index (after ...
Definition: voxel_grid.h:619
bool getFilterLimitsNegative() const
Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
Definition: voxel_grid.h:785
std::vector< int > getNeighborCentroidIndices(float x, float y, float z, const Eigen::MatrixXi &relative_coordinates) const
Returns the indices in the resulting downsampled cloud of the points at the specified grid coordinate...
Definition: voxel_grid.h:647
std::string filter_field_name_
The desired user filter field name.
Definition: voxel_grid.h:816
std::vector< int > leaf_layout_
The leaf layout information for fast access to cells relative to current position.
Definition: voxel_grid.h:808
void setDownsampleAllData(bool downsample)
Set to true if all fields need to be downsampled, or false if just XYZ.
Definition: voxel_grid.h:568
void setFilterLimits(const double &limit_min, const double &limit_max)
Set the field filter limits.
Definition: voxel_grid.h:743
Eigen::Vector3f getLeafSize() const
Get the voxel grid leaf size.
Definition: voxel_grid.h:562
Eigen::Vector3i getNrDivisions() const
Get the number of divisions along all 3 axes (after filtering is performed).
Definition: voxel_grid.h:613
Eigen::Vector3i getMinBoxCoordinates() const
Get the minimum coordinates of the bounding box (after filtering is performed).
Definition: voxel_grid.h:601
void applyFilter(PCLPointCloud2 &output) override
Downsample a Point Cloud using a voxelized grid approach.
unsigned int getMinimumPointsNumberPerVoxel() const
Return the minimum number of points required for a voxel to be used.
Definition: voxel_grid.h:585
void setLeafSize(const Eigen::Vector4f &leaf_size)
Set the voxel grid leaf size.
Definition: voxel_grid.h:534
void getFilterLimits(double &limit_min, double &limit_max) const
Get the field filter limits (min/max) set by the user.
Definition: voxel_grid.h:755
std::vector< int > getNeighborCentroidIndices(float x, float y, float z, const std::vector< Eigen::Vector3i, Eigen::aligned_allocator< Eigen::Vector3i > > &relative_coordinates) const
Returns the indices in the resulting downsampled cloud of the points at the specified grid coordinate...
Definition: voxel_grid.h:676
Eigen::Vector3i getGridCoordinates(float x, float y, float z) const
Returns the corresponding (i,j,k) coordinates in the grid of point (x,y,z).
Definition: voxel_grid.h:698
bool getDownsampleAllData() const
Get the state of the internal downsampling parameter (true if all fields need to be downsampled,...
Definition: voxel_grid.h:574
bool getSaveLeafLayout() const
Returns true if leaf layout information will to be saved for later access.
Definition: voxel_grid.h:595
std::vector< int > getLeafLayout() const
Returns the layout of the leafs for fast access to cells relative to current position.
Definition: voxel_grid.h:690
std::string const getFilterFieldName() const
Get the name of the field used for filtering.
Definition: voxel_grid.h:733
Eigen::Vector3i getMaxBoxCoordinates() const
Get the minimum coordinates of the bounding box (after filtering is performed).
Definition: voxel_grid.h:607
void setFilterFieldName(const std::string &field_name)
Provide the name of the field to be used for filtering data.
Definition: voxel_grid.h:726
void setSaveLeafLayout(bool save_leaf_layout)
Set to true if leaf layout information needs to be saved for later access.
Definition: voxel_grid.h:591
void setFilterLimitsNegative(const bool limit_negative)
Set to true if we want to return the data outside the interval specified by setFilterLimits (min,...
Definition: voxel_grid.h:766
void setLeafSize(float lx, float ly, float lz)
Set the voxel grid leaf size.
Definition: voxel_grid.h:550
Eigen::Array4f inverse_leaf_size_
Internal leaf sizes stored as 1/leaf_size_ for efficiency reasons.
Definition: voxel_grid.h:795
~VoxelGrid() override=default
Destructor.
void setMinimumPointsNumberPerVoxel(unsigned int min_points_per_voxel)
Set the minimum number of points required for a voxel to be used.
Definition: voxel_grid.h:580
int getCentroidIndex(float x, float y, float z) const
Returns the index in the resulting downsampled cloud of the specified point.
Definition: voxel_grid.h:629
Eigen::Vector4f leaf_size_
The size of a leaf.
Definition: voxel_grid.h:792
VoxelGrid assembles a local 3D grid over a given PointCloud, and downsamples + filters the data.
Definition: voxel_grid.h:177
Eigen::Vector3i getGridCoordinates(float x, float y, float z) const
Returns the corresponding (i,j,k) coordinates in the grid of point (x,y,z).
Definition: voxel_grid.h:356
void setFilterFieldName(const std::string &field_name)
Provide the name of the field to be used for filtering data.
Definition: voxel_grid.h:384
void setDownsampleAllData(bool downsample)
Set to true if all fields need to be downsampled, or false if just XYZ.
Definition: voxel_grid.h:248
bool downsample_all_data_
Set to true if all fields need to be downsampled, or false if just XYZ.
Definition: voxel_grid.h:456
Eigen::Vector3i getDivisionMultiplier() const
Get the multipliers to be applied to the grid coordinates in order to find the centroid index (after ...
Definition: voxel_grid.h:299
bool getFilterLimitsNegative() const
Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
Definition: voxel_grid.h:443
void setFilterLimitsNegative(const bool limit_negative)
Set to true if we want to return the data outside the interval specified by setFilterLimits (min,...
Definition: voxel_grid.h:424
Eigen::Vector3i getMaxBoxCoordinates() const
Get the minimum coordinates of the bounding box (after filtering is performed).
Definition: voxel_grid.h:287
Eigen::Vector4i max_b_
Definition: voxel_grid.h:465
unsigned int min_points_per_voxel_
Minimum number of points per voxel for the centroid to be computed.
Definition: voxel_grid.h:480
void applyFilter(PointCloud &output) override
Downsample a Point Cloud using a voxelized grid approach.
Definition: voxel_grid.hpp:226
unsigned int getMinimumPointsNumberPerVoxel() const
Return the minimum number of points required for a voxel to be used.
Definition: voxel_grid.h:265
bool getDownsampleAllData() const
Get the state of the internal downsampling parameter (true if all fields need to be downsampled,...
Definition: voxel_grid.h:254
std::vector< int > leaf_layout_
The leaf layout information for fast access to cells relative to current position.
Definition: voxel_grid.h:462
void getFilterLimits(double &limit_min, double &limit_max) const
Get the field filter limits (min/max) set by the user.
Definition: voxel_grid.h:413
Eigen::Vector4i divb_mul_
Definition: voxel_grid.h:465
typename pcl::traits::fieldList< PointT >::type FieldList
Definition: voxel_grid.h:482
int getCentroidIndex(const PointT &p) const
Returns the index in the resulting downsampled cloud of the specified point.
Definition: voxel_grid.h:310
Eigen::Vector3i getNrDivisions() const
Get the number of divisions along all 3 axes (after filtering is performed).
Definition: voxel_grid.h:293
bool save_leaf_layout_
Set to true if leaf layout information needs to be saved in leaf_layout_.
Definition: voxel_grid.h:459
bool filter_limit_negative_
Set to true if we want to return the data outside (filter_limit_min_;filter_limit_max_).
Definition: voxel_grid.h:477
std::vector< int > getLeafLayout() const
Returns the layout of the leafs for fast access to cells relative to current position.
Definition: voxel_grid.h:348
int getCentroidIndexAt(const Eigen::Vector3i &ijk) const
Returns the index in the downsampled cloud corresponding to a given set of coordinates.
Definition: voxel_grid.h:367
void setLeafSize(const Eigen::Vector4f &leaf_size)
Set the voxel grid leaf size.
Definition: voxel_grid.h:214
Eigen::Vector4i min_b_
The minimum and maximum bin coordinates, the number of divisions, and the division multiplier.
Definition: voxel_grid.h:465
void setSaveLeafLayout(bool save_leaf_layout)
Set to true if leaf layout information needs to be saved for later access.
Definition: voxel_grid.h:271
double filter_limit_max_
The maximum allowed filter value a point will be considered from.
Definition: voxel_grid.h:474
void setMinimumPointsNumberPerVoxel(unsigned int min_points_per_voxel)
Set the minimum number of points required for a voxel to be used.
Definition: voxel_grid.h:260
std::vector< int > getNeighborCentroidIndices(const PointT &reference_point, const Eigen::MatrixXi &relative_coordinates) const
Returns the indices in the resulting downsampled cloud of the points at the specified grid coordinate...
Definition: voxel_grid.h:324
PCL_MAKE_ALIGNED_OPERATOR_NEW VoxelGrid()
Empty constructor.
Definition: voxel_grid.h:196
std::string filter_field_name_
The desired user filter field name.
Definition: voxel_grid.h:468
Eigen::Vector4f leaf_size_
The size of a leaf.
Definition: voxel_grid.h:450
double filter_limit_min_
The minimum allowed filter value a point will be considered from.
Definition: voxel_grid.h:471
Eigen::Vector3f getLeafSize() const
Get the voxel grid leaf size.
Definition: voxel_grid.h:242
void setLeafSize(float lx, float ly, float lz)
Set the voxel grid leaf size.
Definition: voxel_grid.h:230
std::string const getFilterFieldName() const
Get the name of the field used for filtering.
Definition: voxel_grid.h:391
Eigen::Vector3i getMinBoxCoordinates() const
Get the minimum coordinates of the bounding box (after filtering is performed).
Definition: voxel_grid.h:281
Eigen::Array4f inverse_leaf_size_
Internal leaf sizes stored as 1/leaf_size_ for efficiency reasons.
Definition: voxel_grid.h:453
~VoxelGrid() override=default
Destructor.
bool getSaveLeafLayout() const
Returns true if leaf layout information will to be saved for later access.
Definition: voxel_grid.h:275
Eigen::Vector4i div_b_
Definition: voxel_grid.h:465
void setFilterLimits(const double &limit_min, const double &limit_max)
Set the field filter limits.
Definition: voxel_grid.h:401
void getMinMax3D(const pcl::PointCloud< PointT > &cloud, PointT &min_pt, PointT &max_pt)
Get the minimum and maximum values on each of the 3 (x-y-z) dimensions in a given pointcloud.
Definition: common.hpp:295
#define PCL_MAKE_ALIGNED_OPERATOR_NEW
Macro to signal a class requires a custom allocator.
Definition: memory.h:63
Eigen::MatrixXi getAllNeighborCellIndices()
Get the relative cell indices of all the 26 neighbors.
Definition: voxel_grid.h:120
Eigen::MatrixXi getHalfNeighborCellIndices()
Get the relative cell indices of the "upper half" 13 neighbors.
Definition: voxel_grid.h:83
Definition: bfgs.h:10
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:133
PCLPointCloud2::ConstPtr PCLPointCloud2ConstPtr
#define PCL_EXPORTS
Definition: pcl_macros.h:323
#define PCL_DEPRECATED(Major, Minor, Message)
macro for compatibility across compilers and help remove old deprecated items for the Major....
Definition: pcl_macros.h:156
shared_ptr< ::pcl::PCLPointCloud2 > Ptr
shared_ptr< const ::pcl::PCLPointCloud2 > ConstPtr
A point structure representing Euclidean xyz coordinates, and the RGB color.