Point Cloud Library (PCL) 1.12.1
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 <cfloat> // for FLT_MAX
44
45namespace 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
187
188 public:
189
190 using Ptr = shared_ptr<VoxelGrid<PointT> >;
191 using ConstPtr = shared_ptr<const VoxelGrid<PointT> >;
192
193 /** \brief Empty constructor. */
195 leaf_size_ (Eigen::Vector4f::Zero ()),
196 inverse_leaf_size_ (Eigen::Array4f::Zero ()),
198 save_leaf_layout_ (false),
199 min_b_ (Eigen::Vector4i::Zero ()),
200 max_b_ (Eigen::Vector4i::Zero ()),
201 div_b_ (Eigen::Vector4i::Zero ()),
202 divb_mul_ (Eigen::Vector4i::Zero ()),
204 filter_limit_min_ (-FLT_MAX),
205 filter_limit_max_ (FLT_MAX),
208 {
209 filter_name_ = "VoxelGrid";
210 }
211
212 /** \brief Destructor. */
214 {
215 }
216
217 /** \brief Set the voxel grid leaf size.
218 * \param[in] leaf_size the voxel grid leaf size
219 */
220 inline void
221 setLeafSize (const Eigen::Vector4f &leaf_size)
222 {
223 leaf_size_ = leaf_size;
224 // Avoid division errors
225 if (leaf_size_[3] == 0)
226 leaf_size_[3] = 1;
227 // Use multiplications instead of divisions
228 inverse_leaf_size_ = Eigen::Array4f::Ones () / leaf_size_.array ();
229 }
230
231 /** \brief Set the voxel grid leaf size.
232 * \param[in] lx the leaf size for X
233 * \param[in] ly the leaf size for Y
234 * \param[in] lz the leaf size for Z
235 */
236 inline void
237 setLeafSize (float lx, float ly, float lz)
238 {
239 leaf_size_[0] = lx; leaf_size_[1] = ly; leaf_size_[2] = lz;
240 // Avoid division errors
241 if (leaf_size_[3] == 0)
242 leaf_size_[3] = 1;
243 // Use multiplications instead of divisions
244 inverse_leaf_size_ = Eigen::Array4f::Ones () / leaf_size_.array ();
245 }
246
247 /** \brief Get the voxel grid leaf size. */
248 inline Eigen::Vector3f
249 getLeafSize () const { return (leaf_size_.head<3> ()); }
250
251 /** \brief Set to true if all fields need to be downsampled, or false if just XYZ.
252 * \param[in] downsample the new value (true/false)
253 */
254 inline void
255 setDownsampleAllData (bool downsample) { downsample_all_data_ = downsample; }
256
257 /** \brief Get the state of the internal downsampling parameter (true if
258 * all fields need to be downsampled, false if just XYZ).
259 */
260 inline bool
262
263 /** \brief Set the minimum number of points required for a voxel to be used.
264 * \param[in] min_points_per_voxel the minimum number of points for required for a voxel to be used
265 */
266 inline void
267 setMinimumPointsNumberPerVoxel (unsigned int min_points_per_voxel) { min_points_per_voxel_ = min_points_per_voxel; }
268
269 /** \brief Return the minimum number of points required for a voxel to be used.
270 */
271 inline unsigned int
273
274 /** \brief Set to true if leaf layout information needs to be saved for later access.
275 * \param[in] save_leaf_layout the new value (true/false)
276 */
277 inline void
278 setSaveLeafLayout (bool save_leaf_layout) { save_leaf_layout_ = save_leaf_layout; }
279
280 /** \brief Returns true if leaf layout information will to be saved for later access. */
281 inline bool
283
284 /** \brief Get the minimum coordinates of the bounding box (after
285 * filtering is performed).
286 */
287 inline Eigen::Vector3i
288 getMinBoxCoordinates () const { return (min_b_.head<3> ()); }
289
290 /** \brief Get the minimum coordinates of the bounding box (after
291 * filtering is performed).
292 */
293 inline Eigen::Vector3i
294 getMaxBoxCoordinates () const { return (max_b_.head<3> ()); }
295
296 /** \brief Get the number of divisions along all 3 axes (after filtering
297 * is performed).
298 */
299 inline Eigen::Vector3i
300 getNrDivisions () const { return (div_b_.head<3> ()); }
301
302 /** \brief Get the multipliers to be applied to the grid coordinates in
303 * order to find the centroid index (after filtering is performed).
304 */
305 inline Eigen::Vector3i
306 getDivisionMultiplier () const { return (divb_mul_.head<3> ()); }
307
308 /** \brief Returns the index in the resulting downsampled cloud of the specified point.
309 *
310 * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering
311 * performed, and that the point is inside the grid, to avoid invalid access (or use
312 * getGridCoordinates+getCentroidIndexAt)
313 *
314 * \param[in] p the point to get the index at
315 */
316 inline int
317 getCentroidIndex (const PointT &p) const
318 {
319 return (leaf_layout_.at ((Eigen::Vector4i (static_cast<int> (std::floor (p.x * inverse_leaf_size_[0])),
320 static_cast<int> (std::floor (p.y * inverse_leaf_size_[1])),
321 static_cast<int> (std::floor (p.z * inverse_leaf_size_[2])), 0) - min_b_).dot (divb_mul_)));
322 }
323
324 /** \brief Returns the indices in the resulting downsampled cloud of the points at the specified grid coordinates,
325 * relative to the grid coordinates of the specified point (or -1 if the cell was empty/out of bounds).
326 * \param[in] reference_point the coordinates of the reference point (corresponding cell is allowed to be empty/out of bounds)
327 * \param[in] relative_coordinates matrix with the columns being the coordinates of the requested cells, relative to the reference point's cell
328 * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering performed
329 */
330 inline std::vector<int>
331 getNeighborCentroidIndices (const PointT &reference_point, const Eigen::MatrixXi &relative_coordinates) const
332 {
333 Eigen::Vector4i ijk (static_cast<int> (std::floor (reference_point.x * inverse_leaf_size_[0])),
334 static_cast<int> (std::floor (reference_point.y * inverse_leaf_size_[1])),
335 static_cast<int> (std::floor (reference_point.z * inverse_leaf_size_[2])), 0);
336 Eigen::Array4i diff2min = min_b_ - ijk;
337 Eigen::Array4i diff2max = max_b_ - ijk;
338 std::vector<int> neighbors (relative_coordinates.cols());
339 for (Eigen::Index ni = 0; ni < relative_coordinates.cols (); ni++)
340 {
341 Eigen::Vector4i displacement = (Eigen::Vector4i() << relative_coordinates.col(ni), 0).finished();
342 // checking if the specified cell is in the grid
343 if ((diff2min <= displacement.array()).all() && (diff2max >= displacement.array()).all())
344 neighbors[ni] = leaf_layout_[((ijk + displacement - min_b_).dot (divb_mul_))]; // .at() can be omitted
345 else
346 neighbors[ni] = -1; // cell is out of bounds, consider it empty
347 }
348 return (neighbors);
349 }
350
351 /** \brief Returns the layout of the leafs for fast access to cells relative to current position.
352 * \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)
353 */
354 inline std::vector<int>
355 getLeafLayout () const { return (leaf_layout_); }
356
357 /** \brief Returns the corresponding (i,j,k) coordinates in the grid of point (x,y,z).
358 * \param[in] x the X point coordinate to get the (i, j, k) index at
359 * \param[in] y the Y point coordinate to get the (i, j, k) index at
360 * \param[in] z the Z point coordinate to get the (i, j, k) index at
361 */
362 inline Eigen::Vector3i
363 getGridCoordinates (float x, float y, float z) const
364 {
365 return (Eigen::Vector3i (static_cast<int> (std::floor (x * inverse_leaf_size_[0])),
366 static_cast<int> (std::floor (y * inverse_leaf_size_[1])),
367 static_cast<int> (std::floor (z * inverse_leaf_size_[2]))));
368 }
369
370 /** \brief Returns the index in the downsampled cloud corresponding to a given set of coordinates.
371 * \param[in] ijk the coordinates (i,j,k) in the grid (-1 if empty)
372 */
373 inline int
374 getCentroidIndexAt (const Eigen::Vector3i &ijk) const
375 {
376 int idx = ((Eigen::Vector4i() << ijk, 0).finished() - min_b_).dot (divb_mul_);
377 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
378 {
379 //if (verbose)
380 // 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 ());
381 return (-1);
382 }
383 return (leaf_layout_[idx]);
384 }
385
386 /** \brief Provide the name of the field to be used for filtering data. In conjunction with \a setFilterLimits,
387 * points having values outside this interval will be discarded.
388 * \param[in] field_name the name of the field that contains values used for filtering
389 */
390 inline void
391 setFilterFieldName (const std::string &field_name)
392 {
393 filter_field_name_ = field_name;
394 }
395
396 /** \brief Get the name of the field used for filtering. */
397 inline std::string const
399 {
400 return (filter_field_name_);
401 }
402
403 /** \brief Set the field filter limits. All points having field values outside this interval will be discarded.
404 * \param[in] limit_min the minimum allowed field value
405 * \param[in] limit_max the maximum allowed field value
406 */
407 inline void
408 setFilterLimits (const double &limit_min, const double &limit_max)
409 {
410 filter_limit_min_ = limit_min;
411 filter_limit_max_ = limit_max;
412 }
413
414 /** \brief Get the field filter limits (min/max) set by the user. The default values are -FLT_MAX, FLT_MAX.
415 * \param[out] limit_min the minimum allowed field value
416 * \param[out] limit_max the maximum allowed field value
417 */
418 inline void
419 getFilterLimits (double &limit_min, double &limit_max) const
420 {
421 limit_min = filter_limit_min_;
422 limit_max = filter_limit_max_;
423 }
424
425 /** \brief Set to true if we want to return the data outside the interval specified by setFilterLimits (min, max).
426 * Default: false.
427 * \param[in] limit_negative return data inside the interval (false) or outside (true)
428 */
429 inline void
430 setFilterLimitsNegative (const bool limit_negative)
431 {
432 filter_limit_negative_ = limit_negative;
433 }
434
435 /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
436 * \param[out] limit_negative true if data \b outside the interval [min; max] is to be returned, false otherwise
437 */
438 PCL_DEPRECATED(1, 16, "use bool getFilterLimitsNegative() instead")
439 inline void
440 getFilterLimitsNegative (bool &limit_negative) const
441 {
442 limit_negative = filter_limit_negative_;
443 }
444
445 /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
446 * \return true if data \b outside the interval [min; max] is to be returned, false otherwise
447 */
448 inline bool
450 {
451 return (filter_limit_negative_);
452 }
453
454 protected:
455 /** \brief The size of a leaf. */
456 Eigen::Vector4f leaf_size_;
457
458 /** \brief Internal leaf sizes stored as 1/leaf_size_ for efficiency reasons. */
459 Eigen::Array4f inverse_leaf_size_;
460
461 /** \brief Set to true if all fields need to be downsampled, or false if just XYZ. */
463
464 /** \brief Set to true if leaf layout information needs to be saved in \a leaf_layout_. */
466
467 /** \brief The leaf layout information for fast access to cells relative to current position **/
468 std::vector<int> leaf_layout_;
469
470 /** \brief The minimum and maximum bin coordinates, the number of divisions, and the division multiplier. */
471 Eigen::Vector4i min_b_, max_b_, div_b_, divb_mul_;
472
473 /** \brief The desired user filter field name. */
475
476 /** \brief The minimum allowed filter value a point will be considered from. */
478
479 /** \brief The maximum allowed filter value a point will be considered from. */
481
482 /** \brief Set to true if we want to return the data outside (\a filter_limit_min_;\a filter_limit_max_). Default: false. */
484
485 /** \brief Minimum number of points per voxel for the centroid to be computed */
487
488 using FieldList = typename pcl::traits::fieldList<PointT>::type;
489
490 /** \brief Downsample a Point Cloud using a voxelized grid approach
491 * \param[out] output the resultant point cloud message
492 */
493 void
494 applyFilter (PointCloud &output) override;
495 };
496
497 /** \brief VoxelGrid assembles a local 3D grid over a given PointCloud, and downsamples + filters the data.
498 *
499 * The VoxelGrid class creates a *3D voxel grid* (think about a voxel
500 * grid as a set of tiny 3D boxes in space) over the input point cloud data.
501 * Then, in each *voxel* (i.e., 3D box), all the points present will be
502 * approximated (i.e., *downsampled*) with their centroid. This approach is
503 * a bit slower than approximating them with the center of the voxel, but it
504 * represents the underlying surface more accurately.
505 *
506 * \author Radu B. Rusu, Bastian Steder, Radoslaw Cybulski
507 * \ingroup filters
508 */
509 template <>
510 class PCL_EXPORTS VoxelGrid<pcl::PCLPointCloud2> : public Filter<pcl::PCLPointCloud2>
511 {
514
518
519 public:
520 /** \brief Empty constructor. */
522 leaf_size_ (Eigen::Vector4f::Zero ()),
523 inverse_leaf_size_ (Eigen::Array4f::Zero ()),
524 downsample_all_data_ (true),
525 save_leaf_layout_ (false),
526 min_b_ (Eigen::Vector4i::Zero ()),
527 max_b_ (Eigen::Vector4i::Zero ()),
528 div_b_ (Eigen::Vector4i::Zero ()),
529 divb_mul_ (Eigen::Vector4i::Zero ()),
530 filter_field_name_ (""),
531 filter_limit_min_ (-FLT_MAX),
532 filter_limit_max_ (FLT_MAX),
533 filter_limit_negative_ (false),
534 min_points_per_voxel_ (0)
535 {
536 filter_name_ = "VoxelGrid";
537 }
538
539 /** \brief Destructor. */
541 {
542 }
543
544 /** \brief Set the voxel grid leaf size.
545 * \param[in] leaf_size the voxel grid leaf size
546 */
547 inline void
548 setLeafSize (const Eigen::Vector4f &leaf_size)
549 {
550 leaf_size_ = leaf_size;
551 // Avoid division errors
552 if (leaf_size_[3] == 0)
553 leaf_size_[3] = 1;
554 // Use multiplications instead of divisions
555 inverse_leaf_size_ = Eigen::Array4f::Ones () / leaf_size_.array ();
556 }
557
558 /** \brief Set the voxel grid leaf size.
559 * \param[in] lx the leaf size for X
560 * \param[in] ly the leaf size for Y
561 * \param[in] lz the leaf size for Z
562 */
563 inline void
564 setLeafSize (float lx, float ly, float lz)
565 {
566 leaf_size_[0] = lx; leaf_size_[1] = ly; leaf_size_[2] = lz;
567 // Avoid division errors
568 if (leaf_size_[3] == 0)
569 leaf_size_[3] = 1;
570 // Use multiplications instead of divisions
571 inverse_leaf_size_ = Eigen::Array4f::Ones () / leaf_size_.array ();
572 }
573
574 /** \brief Get the voxel grid leaf size. */
575 inline Eigen::Vector3f
576 getLeafSize () const { return (leaf_size_.head<3> ()); }
577
578 /** \brief Set to true if all fields need to be downsampled, or false if just XYZ.
579 * \param[in] downsample the new value (true/false)
580 */
581 inline void
582 setDownsampleAllData (bool downsample) { downsample_all_data_ = downsample; }
583
584 /** \brief Get the state of the internal downsampling parameter (true if
585 * all fields need to be downsampled, false if just XYZ).
586 */
587 inline bool
588 getDownsampleAllData () const { return (downsample_all_data_); }
589
590 /** \brief Set the minimum number of points required for a voxel to be used.
591 * \param[in] min_points_per_voxel the minimum number of points for required for a voxel to be used
592 */
593 inline void
594 setMinimumPointsNumberPerVoxel (unsigned int min_points_per_voxel) { min_points_per_voxel_ = min_points_per_voxel; }
595
596 /** \brief Return the minimum number of points required for a voxel to be used.
597 */
598 inline unsigned int
599 getMinimumPointsNumberPerVoxel () const { return min_points_per_voxel_; }
600
601 /** \brief Set to true if leaf layout information needs to be saved for later access.
602 * \param[in] save_leaf_layout the new value (true/false)
603 */
604 inline void
605 setSaveLeafLayout (bool save_leaf_layout) { save_leaf_layout_ = save_leaf_layout; }
606
607 /** \brief Returns true if leaf layout information will to be saved for later access. */
608 inline bool
609 getSaveLeafLayout () const { return (save_leaf_layout_); }
610
611 /** \brief Get the minimum coordinates of the bounding box (after
612 * filtering is performed).
613 */
614 inline Eigen::Vector3i
615 getMinBoxCoordinates () const { return (min_b_.head<3> ()); }
616
617 /** \brief Get the minimum coordinates of the bounding box (after
618 * filtering is performed).
619 */
620 inline Eigen::Vector3i
621 getMaxBoxCoordinates () const { return (max_b_.head<3> ()); }
622
623 /** \brief Get the number of divisions along all 3 axes (after filtering
624 * is performed).
625 */
626 inline Eigen::Vector3i
627 getNrDivisions () const { return (div_b_.head<3> ()); }
628
629 /** \brief Get the multipliers to be applied to the grid coordinates in
630 * order to find the centroid index (after filtering is performed).
631 */
632 inline Eigen::Vector3i
633 getDivisionMultiplier () const { return (divb_mul_.head<3> ()); }
634
635 /** \brief Returns the index in the resulting downsampled cloud of the specified point.
636 * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering performed,
637 * and that the point is inside the grid, to avoid invalid access (or use getGridCoordinates+getCentroidIndexAt)
638 * \param[in] x the X point coordinate to get the index at
639 * \param[in] y the Y point coordinate to get the index at
640 * \param[in] z the Z point coordinate to get the index at
641 */
642 inline int
643 getCentroidIndex (float x, float y, float z) const
644 {
645 return (leaf_layout_.at ((Eigen::Vector4i (static_cast<int> (std::floor (x * inverse_leaf_size_[0])),
646 static_cast<int> (std::floor (y * inverse_leaf_size_[1])),
647 static_cast<int> (std::floor (z * inverse_leaf_size_[2])),
648 0)
649 - min_b_).dot (divb_mul_)));
650 }
651
652 /** \brief Returns the indices in the resulting downsampled cloud of the points at the specified grid coordinates,
653 * relative to the grid coordinates of the specified point (or -1 if the cell was empty/out of bounds).
654 * \param[in] x the X coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
655 * \param[in] y the Y coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
656 * \param[in] z the Z coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
657 * \param[out] relative_coordinates matrix with the columns being the coordinates of the requested cells, relative to the reference point's cell
658 * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering performed
659 */
660 inline std::vector<int>
661 getNeighborCentroidIndices (float x, float y, float z, const Eigen::MatrixXi &relative_coordinates) const
662 {
663 Eigen::Vector4i ijk (static_cast<int> (std::floor (x * inverse_leaf_size_[0])),
664 static_cast<int> (std::floor (y * inverse_leaf_size_[1])),
665 static_cast<int> (std::floor (z * inverse_leaf_size_[2])), 0);
666 Eigen::Array4i diff2min = min_b_ - ijk;
667 Eigen::Array4i diff2max = max_b_ - ijk;
668 std::vector<int> neighbors (relative_coordinates.cols());
669 for (Eigen::Index ni = 0; ni < relative_coordinates.cols (); ni++)
670 {
671 Eigen::Vector4i displacement = (Eigen::Vector4i() << relative_coordinates.col(ni), 0).finished();
672 // checking if the specified cell is in the grid
673 if ((diff2min <= displacement.array()).all() && (diff2max >= displacement.array()).all())
674 neighbors[ni] = leaf_layout_[((ijk + displacement - min_b_).dot (divb_mul_))]; // .at() can be omitted
675 else
676 neighbors[ni] = -1; // cell is out of bounds, consider it empty
677 }
678 return (neighbors);
679 }
680
681 /** \brief Returns the indices in the resulting downsampled cloud of the points at the specified grid coordinates,
682 * relative to the grid coordinates of the specified point (or -1 if the cell was empty/out of bounds).
683 * \param[in] x the X coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
684 * \param[in] y the Y coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
685 * \param[in] z the Z coordinate of the reference point (corresponding cell is allowed to be empty/out of bounds)
686 * \param[out] relative_coordinates vector with the elements being the coordinates of the requested cells, relative to the reference point's cell
687 * \note for efficiency, user must make sure that the saving of the leaf layout is enabled and filtering performed
688 */
689 inline std::vector<int>
690 getNeighborCentroidIndices (float x, float y, float z, const std::vector<Eigen::Vector3i, Eigen::aligned_allocator<Eigen::Vector3i> > &relative_coordinates) const
691 {
692 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);
693 std::vector<int> neighbors;
694 neighbors.reserve (relative_coordinates.size ());
695 for (const auto &relative_coordinate : relative_coordinates)
696 neighbors.push_back (leaf_layout_[(ijk + (Eigen::Vector4i() << relative_coordinate, 0).finished() - min_b_).dot (divb_mul_)]);
697 return (neighbors);
698 }
699
700 /** \brief Returns the layout of the leafs for fast access to cells relative to current position.
701 * \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)
702 */
703 inline std::vector<int>
704 getLeafLayout () const { return (leaf_layout_); }
705
706 /** \brief Returns the corresponding (i,j,k) coordinates in the grid of point (x,y,z).
707 * \param[in] x the X point coordinate to get the (i, j, k) index at
708 * \param[in] y the Y point coordinate to get the (i, j, k) index at
709 * \param[in] z the Z point coordinate to get the (i, j, k) index at
710 */
711 inline Eigen::Vector3i
712 getGridCoordinates (float x, float y, float z) const
713 {
714 return (Eigen::Vector3i (static_cast<int> (std::floor (x * inverse_leaf_size_[0])),
715 static_cast<int> (std::floor (y * inverse_leaf_size_[1])),
716 static_cast<int> (std::floor (z * inverse_leaf_size_[2]))));
717 }
718
719 /** \brief Returns the index in the downsampled cloud corresponding to a given set of coordinates.
720 * \param[in] ijk the coordinates (i,j,k) in the grid (-1 if empty)
721 */
722 inline int
723 getCentroidIndexAt (const Eigen::Vector3i &ijk) const
724 {
725 int idx = ((Eigen::Vector4i() << ijk, 0).finished() - min_b_).dot (divb_mul_);
726 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
727 {
728 //if (verbose)
729 // 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 ());
730 return (-1);
731 }
732 return (leaf_layout_[idx]);
733 }
734
735 /** \brief Provide the name of the field to be used for filtering data. In conjunction with \a setFilterLimits,
736 * points having values outside this interval will be discarded.
737 * \param[in] field_name the name of the field that contains values used for filtering
738 */
739 inline void
740 setFilterFieldName (const std::string &field_name)
741 {
742 filter_field_name_ = field_name;
743 }
744
745 /** \brief Get the name of the field used for filtering. */
746 inline std::string const
748 {
749 return (filter_field_name_);
750 }
751
752 /** \brief Set the field filter limits. All points having field values outside this interval will be discarded.
753 * \param[in] limit_min the minimum allowed field value
754 * \param[in] limit_max the maximum allowed field value
755 */
756 inline void
757 setFilterLimits (const double &limit_min, const double &limit_max)
758 {
759 filter_limit_min_ = limit_min;
760 filter_limit_max_ = limit_max;
761 }
762
763 /** \brief Get the field filter limits (min/max) set by the user. The default values are -FLT_MAX, FLT_MAX.
764 * \param[out] limit_min the minimum allowed field value
765 * \param[out] limit_max the maximum allowed field value
766 */
767 inline void
768 getFilterLimits (double &limit_min, double &limit_max) const
769 {
770 limit_min = filter_limit_min_;
771 limit_max = filter_limit_max_;
772 }
773
774 /** \brief Set to true if we want to return the data outside the interval specified by setFilterLimits (min, max).
775 * Default: false.
776 * \param[in] limit_negative return data inside the interval (false) or outside (true)
777 */
778 inline void
779 setFilterLimitsNegative (const bool limit_negative)
780 {
781 filter_limit_negative_ = limit_negative;
782 }
783
784 /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
785 * \param[out] limit_negative true if data \b outside the interval [min; max] is to be returned, false otherwise
786 */
787 PCL_DEPRECATED(1, 16, "use bool getFilterLimitsNegative() instead")
788 inline void
789 getFilterLimitsNegative (bool &limit_negative) const
790 {
791 limit_negative = filter_limit_negative_;
792 }
793
794 /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
795 * \return true if data \b outside the interval [min; max] is to be returned, false otherwise
796 */
797 inline bool
799 {
800 return (filter_limit_negative_);
801 }
802
803 protected:
804 /** \brief The size of a leaf. */
805 Eigen::Vector4f leaf_size_;
806
807 /** \brief Internal leaf sizes stored as 1/leaf_size_ for efficiency reasons. */
808 Eigen::Array4f inverse_leaf_size_;
809
810 /** \brief Set to true if all fields need to be downsampled, or false if just XYZ. */
812
813 /** \brief Set to true if leaf layout information needs to be saved in \a
814 * leaf_layout.
815 */
817
818 /** \brief The leaf layout information for fast access to cells relative
819 * to current position
820 */
821 std::vector<int> leaf_layout_;
822
823 /** \brief The minimum and maximum bin coordinates, the number of
824 * divisions, and the division multiplier.
825 */
826 Eigen::Vector4i min_b_, max_b_, div_b_, divb_mul_;
827
828 /** \brief The desired user filter field name. */
830
831 /** \brief The minimum allowed filter value a point will be considered from. */
833
834 /** \brief The maximum allowed filter value a point will be considered from. */
836
837 /** \brief Set to true if we want to return the data outside (\a filter_limit_min_;\a filter_limit_max_). Default: false. */
839
840 /** \brief Minimum number of points per voxel for the centroid to be computed */
842
843 /** \brief Downsample a Point Cloud using a voxelized grid approach
844 * \param[out] output the resultant point cloud
845 */
846 void
847 applyFilter (PCLPointCloud2 &output) override;
848 };
849}
850
851#ifdef PCL_NO_PRECOMPILE
852#include <pcl/filters/impl/voxel_grid.hpp>
853#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:723
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:633
bool getFilterLimitsNegative() const
Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
Definition: voxel_grid.h:798
std::string filter_field_name_
The desired user filter field name.
Definition: voxel_grid.h:829
std::vector< int > leaf_layout_
The leaf layout information for fast access to cells relative to current position.
Definition: voxel_grid.h:821
void setDownsampleAllData(bool downsample)
Set to true if all fields need to be downsampled, or false if just XYZ.
Definition: voxel_grid.h:582
void setFilterLimits(const double &limit_min, const double &limit_max)
Set the field filter limits.
Definition: voxel_grid.h:757
Eigen::Vector3f getLeafSize() const
Get the voxel grid leaf size.
Definition: voxel_grid.h:576
bool downsample_all_data_
Set to true if all fields need to be downsampled, or false if just XYZ.
Definition: voxel_grid.h:811
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:690
Eigen::Vector3i getNrDivisions() const
Get the number of divisions along all 3 axes (after filtering is performed).
Definition: voxel_grid.h:627
Eigen::Vector3i getMinBoxCoordinates() const
Get the minimum coordinates of the bounding box (after filtering is performed).
Definition: voxel_grid.h:615
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:599
void setLeafSize(const Eigen::Vector4f &leaf_size)
Set the voxel grid leaf size.
Definition: voxel_grid.h:548
unsigned int min_points_per_voxel_
Minimum number of points per voxel for the centroid to be computed.
Definition: voxel_grid.h:841
void getFilterLimits(double &limit_min, double &limit_max) const
Get the field filter limits (min/max) set by the user.
Definition: voxel_grid.h:768
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:838
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:661
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:712
bool getDownsampleAllData() const
Get the state of the internal downsampling parameter (true if all fields need to be downsampled,...
Definition: voxel_grid.h:588
bool getSaveLeafLayout() const
Returns true if leaf layout information will to be saved for later access.
Definition: voxel_grid.h:609
std::vector< int > getLeafLayout() const
Returns the layout of the leafs for fast access to cells relative to current position.
Definition: voxel_grid.h:704
std::string const getFilterFieldName() const
Get the name of the field used for filtering.
Definition: voxel_grid.h:747
double filter_limit_max_
The maximum allowed filter value a point will be considered from.
Definition: voxel_grid.h:835
Eigen::Vector3i getMaxBoxCoordinates() const
Get the minimum coordinates of the bounding box (after filtering is performed).
Definition: voxel_grid.h:621
void setFilterFieldName(const std::string &field_name)
Provide the name of the field to be used for filtering data.
Definition: voxel_grid.h:740
double filter_limit_min_
The minimum allowed filter value a point will be considered from.
Definition: voxel_grid.h:832
bool save_leaf_layout_
Set to true if leaf layout information needs to be saved in leaf_layout.
Definition: voxel_grid.h:816
void setSaveLeafLayout(bool save_leaf_layout)
Set to true if leaf layout information needs to be saved for later access.
Definition: voxel_grid.h:605
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:779
void setLeafSize(float lx, float ly, float lz)
Set the voxel grid leaf size.
Definition: voxel_grid.h:564
Eigen::Array4f inverse_leaf_size_
Internal leaf sizes stored as 1/leaf_size_ for efficiency reasons.
Definition: voxel_grid.h:808
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:594
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:643
Eigen::Vector4f leaf_size_
The size of a leaf.
Definition: voxel_grid.h:805
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:363
void setFilterFieldName(const std::string &field_name)
Provide the name of the field to be used for filtering data.
Definition: voxel_grid.h:391
void setDownsampleAllData(bool downsample)
Set to true if all fields need to be downsampled, or false if just XYZ.
Definition: voxel_grid.h:255
bool downsample_all_data_
Set to true if all fields need to be downsampled, or false if just XYZ.
Definition: voxel_grid.h:462
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:306
bool getFilterLimitsNegative() const
Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
Definition: voxel_grid.h:449
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:430
Eigen::Vector3i getMaxBoxCoordinates() const
Get the minimum coordinates of the bounding box (after filtering is performed).
Definition: voxel_grid.h:294
Eigen::Vector4i max_b_
Definition: voxel_grid.h:471
unsigned int min_points_per_voxel_
Minimum number of points per voxel for the centroid to be computed.
Definition: voxel_grid.h:486
void applyFilter(PointCloud &output) override
Downsample a Point Cloud using a voxelized grid approach.
Definition: voxel_grid.hpp:214
unsigned int getMinimumPointsNumberPerVoxel() const
Return the minimum number of points required for a voxel to be used.
Definition: voxel_grid.h:272
bool getDownsampleAllData() const
Get the state of the internal downsampling parameter (true if all fields need to be downsampled,...
Definition: voxel_grid.h:261
std::vector< int > leaf_layout_
The leaf layout information for fast access to cells relative to current position.
Definition: voxel_grid.h:468
void getFilterLimits(double &limit_min, double &limit_max) const
Get the field filter limits (min/max) set by the user.
Definition: voxel_grid.h:419
Eigen::Vector4i divb_mul_
Definition: voxel_grid.h:471
typename pcl::traits::fieldList< PointT >::type FieldList
Definition: voxel_grid.h:488
int getCentroidIndex(const PointT &p) const
Returns the index in the resulting downsampled cloud of the specified point.
Definition: voxel_grid.h:317
Eigen::Vector3i getNrDivisions() const
Get the number of divisions along all 3 axes (after filtering is performed).
Definition: voxel_grid.h:300
bool save_leaf_layout_
Set to true if leaf layout information needs to be saved in leaf_layout_.
Definition: voxel_grid.h:465
VoxelGrid()
Empty constructor.
Definition: voxel_grid.h:194
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:483
~VoxelGrid()
Destructor.
Definition: voxel_grid.h:213
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:374
void setLeafSize(const Eigen::Vector4f &leaf_size)
Set the voxel grid leaf size.
Definition: voxel_grid.h:221
Eigen::Vector4i min_b_
The minimum and maximum bin coordinates, the number of divisions, and the division multiplier.
Definition: voxel_grid.h:471
void setSaveLeafLayout(bool save_leaf_layout)
Set to true if leaf layout information needs to be saved for later access.
Definition: voxel_grid.h:278
double filter_limit_max_
The maximum allowed filter value a point will be considered from.
Definition: voxel_grid.h:480
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:267
std::string filter_field_name_
The desired user filter field name.
Definition: voxel_grid.h:474
std::vector< int > getLeafLayout() const
Returns the layout of the leafs for fast access to cells relative to current position.
Definition: voxel_grid.h:355
Eigen::Vector4f leaf_size_
The size of a leaf.
Definition: voxel_grid.h:456
double filter_limit_min_
The minimum allowed filter value a point will be considered from.
Definition: voxel_grid.h:477
Eigen::Vector3f getLeafSize() const
Get the voxel grid leaf size.
Definition: voxel_grid.h:249
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:331
void setLeafSize(float lx, float ly, float lz)
Set the voxel grid leaf size.
Definition: voxel_grid.h:237
std::string const getFilterFieldName() const
Get the name of the field used for filtering.
Definition: voxel_grid.h:398
Eigen::Vector3i getMinBoxCoordinates() const
Get the minimum coordinates of the bounding box (after filtering is performed).
Definition: voxel_grid.h:288
Eigen::Array4f inverse_leaf_size_
Internal leaf sizes stored as 1/leaf_size_ for efficiency reasons.
Definition: voxel_grid.h:459
bool getSaveLeafLayout() const
Returns true if leaf layout information will to be saved for later access.
Definition: voxel_grid.h:282
Eigen::Vector4i div_b_
Definition: voxel_grid.h:471
void setFilterLimits(const double &limit_min, const double &limit_max)
Set the field filter limits.
Definition: voxel_grid.h:408
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
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.