Point Cloud Library (PCL)  1.11.0-dev
extract_clusters.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/pcl_base.h>
43 
44 #include <pcl/search/pcl_search.h>
45 
46 namespace pcl
47 {
48  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
49  /** \brief Decompose a region of space into clusters based on the Euclidean distance between points
50  * \param cloud the point cloud message
51  * \param tree the spatial locator (e.g., kd-tree) used for nearest neighbors searching
52  * \note the tree has to be created as a spatial locator on \a cloud
53  * \param tolerance the spatial cluster tolerance as a measure in L2 Euclidean space
54  * \param clusters the resultant clusters containing point indices (as a vector of PointIndices)
55  * \param min_pts_per_cluster minimum number of points that a cluster may contain (default: 1)
56  * \param max_pts_per_cluster maximum number of points that a cluster may contain (default: max int)
57  * \ingroup segmentation
58  */
59  template <typename PointT> void
61  const PointCloud<PointT> &cloud, const typename search::Search<PointT>::Ptr &tree,
62  float tolerance, std::vector<PointIndices> &clusters,
63  unsigned int min_pts_per_cluster = 1, unsigned int max_pts_per_cluster = (std::numeric_limits<int>::max) ());
64 
65  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66  /** \brief Decompose a region of space into clusters based on the Euclidean distance between points
67  * \param cloud the point cloud message
68  * \param indices a list of point indices to use from \a cloud
69  * \param tree the spatial locator (e.g., kd-tree) used for nearest neighbors searching
70  * \note the tree has to be created as a spatial locator on \a cloud and \a indices
71  * \param tolerance the spatial cluster tolerance as a measure in L2 Euclidean space
72  * \param clusters the resultant clusters containing point indices (as a vector of PointIndices)
73  * \param min_pts_per_cluster minimum number of points that a cluster may contain (default: 1)
74  * \param max_pts_per_cluster maximum number of points that a cluster may contain (default: max int)
75  * \ingroup segmentation
76  */
77  template <typename PointT> void
79  const PointCloud<PointT> &cloud, const std::vector<int> &indices,
80  const typename search::Search<PointT>::Ptr &tree, float tolerance, std::vector<PointIndices> &clusters,
81  unsigned int min_pts_per_cluster = 1, unsigned int max_pts_per_cluster = (std::numeric_limits<int>::max) ());
82 
83  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84  /** \brief Decompose a region of space into clusters based on the euclidean distance between points, and the normal
85  * angular deviation
86  * \param cloud the point cloud message
87  * \param normals the point cloud message containing normal information
88  * \param tree the spatial locator (e.g., kd-tree) used for nearest neighbors searching
89  * \note the tree has to be created as a spatial locator on \a cloud
90  * \param tolerance the spatial cluster tolerance as a measure in the L2 Euclidean space
91  * \param clusters the resultant clusters containing point indices (as a vector of PointIndices)
92  * \param eps_angle the maximum allowed difference between normals in radians for cluster/region growing
93  * \param min_pts_per_cluster minimum number of points that a cluster may contain (default: 1)
94  * \param max_pts_per_cluster maximum number of points that a cluster may contain (default: max int)
95  * \ingroup segmentation
96  */
97  template <typename PointT, typename Normal> void
99  const PointCloud<PointT> &cloud, const PointCloud<Normal> &normals,
100  float tolerance, const typename KdTree<PointT>::Ptr &tree,
101  std::vector<PointIndices> &clusters, double eps_angle,
102  unsigned int min_pts_per_cluster = 1,
103  unsigned int max_pts_per_cluster = (std::numeric_limits<int>::max) ())
104  {
105  if (tree->getInputCloud ()->size () != cloud.size ())
106  {
107  PCL_ERROR("[pcl::extractEuclideanClusters] Tree built for a different point "
108  "cloud dataset (%zu) than the input cloud (%zu)!\n",
109  static_cast<std::size_t>(tree->getInputCloud()->size()),
110  static_cast<std::size_t>(cloud.size()));
111  return;
112  }
113  if (cloud.size () != normals.size ())
114  {
115  PCL_ERROR("[pcl::extractEuclideanClusters] Number of points in the input point "
116  "cloud (%zu) different than normals (%zu)!\n",
117  static_cast<std::size_t>(cloud.size()),
118  static_cast<std::size_t>(normals.size()));
119  return;
120  }
121 
122  // Create a bool vector of processed point indices, and initialize it to false
123  std::vector<bool> processed (cloud.size (), false);
124 
125  std::vector<int> nn_indices;
126  std::vector<float> nn_distances;
127  // Process all points in the indices vector
128  for (std::size_t i = 0; i < cloud.size (); ++i)
129  {
130  if (processed[i])
131  continue;
132 
133  std::vector<unsigned int> seed_queue;
134  int sq_idx = 0;
135  seed_queue.push_back (static_cast<int> (i));
136 
137  processed[i] = true;
138 
139  while (sq_idx < static_cast<int> (seed_queue.size ()))
140  {
141  // Search for sq_idx
142  if (!tree->radiusSearch (seed_queue[sq_idx], tolerance, nn_indices, nn_distances))
143  {
144  sq_idx++;
145  continue;
146  }
147 
148  for (std::size_t j = 1; j < nn_indices.size (); ++j) // nn_indices[0] should be sq_idx
149  {
150  if (processed[nn_indices[j]]) // Has this point been processed before ?
151  continue;
152 
153  //processed[nn_indices[j]] = true;
154  // [-1;1]
155  double dot_p = normals[i].normal[0] * normals[nn_indices[j]].normal[0] +
156  normals[i].normal[1] * normals[nn_indices[j]].normal[1] +
157  normals[i].normal[2] * normals[nn_indices[j]].normal[2];
158  if ( std::acos (std::abs (dot_p)) < eps_angle )
159  {
160  processed[nn_indices[j]] = true;
161  seed_queue.push_back (nn_indices[j]);
162  }
163  }
164 
165  sq_idx++;
166  }
167 
168  // If this queue is satisfactory, add to the clusters
169  if (seed_queue.size () >= min_pts_per_cluster && seed_queue.size () <= max_pts_per_cluster)
170  {
172  r.indices.resize (seed_queue.size ());
173  for (std::size_t j = 0; j < seed_queue.size (); ++j)
174  r.indices[j] = seed_queue[j];
175 
176  // These two lines should not be needed: (can anyone confirm?) -FF
177  std::sort (r.indices.begin (), r.indices.end ());
178  r.indices.erase (std::unique (r.indices.begin (), r.indices.end ()), r.indices.end ());
179 
180  r.header = cloud.header;
181  clusters.push_back (r); // We could avoid a copy by working directly in the vector
182  }
183  }
184  }
185 
186 
187  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
188  /** \brief Decompose a region of space into clusters based on the euclidean distance between points, and the normal
189  * angular deviation
190  * \param cloud the point cloud message
191  * \param normals the point cloud message containing normal information
192  * \param indices a list of point indices to use from \a cloud
193  * \param tree the spatial locator (e.g., kd-tree) used for nearest neighbors searching
194  * \note the tree has to be created as a spatial locator on \a cloud
195  * \param tolerance the spatial cluster tolerance as a measure in the L2 Euclidean space
196  * \param clusters the resultant clusters containing point indices (as PointIndices)
197  * \param eps_angle the maximum allowed difference between normals in degrees for cluster/region growing
198  * \param min_pts_per_cluster minimum number of points that a cluster may contain (default: 1)
199  * \param max_pts_per_cluster maximum number of points that a cluster may contain (default: max int)
200  * \ingroup segmentation
201  */
202  template <typename PointT, typename Normal>
204  const PointCloud<PointT> &cloud, const PointCloud<Normal> &normals,
205  const std::vector<int> &indices, const typename KdTree<PointT>::Ptr &tree,
206  float tolerance, std::vector<PointIndices> &clusters, double eps_angle,
207  unsigned int min_pts_per_cluster = 1,
208  unsigned int max_pts_per_cluster = (std::numeric_limits<int>::max) ())
209  {
210  // \note If the tree was created over <cloud, indices>, we guarantee a 1-1 mapping between what the tree returns
211  //and indices[i]
212  if (tree->getInputCloud()->size() != cloud.size()) {
213  PCL_ERROR("[pcl::extractEuclideanClusters] Tree built for a different point "
214  "cloud dataset (%zu) than the input cloud (%zu)!\n",
215  static_cast<std::size_t>(tree->getInputCloud()->size()),
216  static_cast<std::size_t>(cloud.size()));
217  return;
218  }
219  if (tree->getIndices()->size() != indices.size()) {
220  PCL_ERROR("[pcl::extractEuclideanClusters] Tree built for a different set of "
221  "indices (%zu) than the input set (%zu)!\n",
222  static_cast<std::size_t>(tree->getIndices()->size()),
223  indices.size());
224  return;
225  }
226  if (cloud.size() != normals.size()) {
227  PCL_ERROR("[pcl::extractEuclideanClusters] Number of points in the input point "
228  "cloud (%zu) different than normals (%zu)!\n",
229  static_cast<std::size_t>(cloud.size()),
230  static_cast<std::size_t>(normals.size()));
231  return;
232  }
233  // Create a bool vector of processed point indices, and initialize it to false
234  std::vector<bool> processed (cloud.size (), false);
235 
236  std::vector<int> nn_indices;
237  std::vector<float> nn_distances;
238  // Process all points in the indices vector
239  for (std::size_t i = 0; i < indices.size (); ++i)
240  {
241  if (processed[indices[i]])
242  continue;
243 
244  std::vector<int> seed_queue;
245  int sq_idx = 0;
246  seed_queue.push_back (indices[i]);
247 
248  processed[indices[i]] = true;
249 
250  while (sq_idx < static_cast<int> (seed_queue.size ()))
251  {
252  // Search for sq_idx
253  if (!tree->radiusSearch (cloud[seed_queue[sq_idx]], tolerance, nn_indices, nn_distances))
254  {
255  sq_idx++;
256  continue;
257  }
258 
259  for (std::size_t j = 1; j < nn_indices.size (); ++j) // nn_indices[0] should be sq_idx
260  {
261  if (processed[nn_indices[j]]) // Has this point been processed before ?
262  continue;
263 
264  //processed[nn_indices[j]] = true;
265  // [-1;1]
266  double dot_p =
267  normals[indices[i]].normal[0] * normals[indices[nn_indices[j]]].normal[0] +
268  normals[indices[i]].normal[1] * normals[indices[nn_indices[j]]].normal[1] +
269  normals[indices[i]].normal[2] * normals[indices[nn_indices[j]]].normal[2];
270  if ( std::acos (std::abs (dot_p)) < eps_angle )
271  {
272  processed[nn_indices[j]] = true;
273  seed_queue.push_back (nn_indices[j]);
274  }
275  }
276 
277  sq_idx++;
278  }
279 
280  // If this queue is satisfactory, add to the clusters
281  if (seed_queue.size () >= min_pts_per_cluster && seed_queue.size () <= max_pts_per_cluster)
282  {
284  r.indices.resize (seed_queue.size ());
285  for (std::size_t j = 0; j < seed_queue.size (); ++j)
286  r.indices[j] = seed_queue[j];
287 
288  // These two lines should not be needed: (can anyone confirm?) -FF
289  std::sort (r.indices.begin (), r.indices.end ());
290  r.indices.erase (std::unique (r.indices.begin (), r.indices.end ()), r.indices.end ());
291 
292  r.header = cloud.header;
293  clusters.push_back (r);
294  }
295  }
296  }
297 
298  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
299  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
300  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
301  /** \brief @b EuclideanClusterExtraction represents a segmentation class for cluster extraction in an Euclidean sense.
302  * \author Radu Bogdan Rusu
303  * \ingroup segmentation
304  */
305  template <typename PointT>
306  class EuclideanClusterExtraction: public PCLBase<PointT>
307  {
309 
310  public:
312  using PointCloudPtr = typename PointCloud::Ptr;
314 
316  using KdTreePtr = typename KdTree::Ptr;
317 
320 
321  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
322  /** \brief Empty constructor. */
324  cluster_tolerance_ (0),
326  max_pts_per_cluster_ (std::numeric_limits<int>::max ())
327  {};
328 
329  /** \brief Provide a pointer to the search object.
330  * \param[in] tree a pointer to the spatial search object.
331  */
332  inline void
333  setSearchMethod (const KdTreePtr &tree)
334  {
335  tree_ = tree;
336  }
337 
338  /** \brief Get a pointer to the search method used.
339  * @todo fix this for a generic search tree
340  */
341  inline KdTreePtr
342  getSearchMethod () const
343  {
344  return (tree_);
345  }
346 
347  /** \brief Set the spatial cluster tolerance as a measure in the L2 Euclidean space
348  * \param[in] tolerance the spatial cluster tolerance as a measure in the L2 Euclidean space
349  */
350  inline void
351  setClusterTolerance (double tolerance)
352  {
353  cluster_tolerance_ = tolerance;
354  }
355 
356  /** \brief Get the spatial cluster tolerance as a measure in the L2 Euclidean space. */
357  inline double
359  {
360  return (cluster_tolerance_);
361  }
362 
363  /** \brief Set the minimum number of points that a cluster needs to contain in order to be considered valid.
364  * \param[in] min_cluster_size the minimum cluster size
365  */
366  inline void
367  setMinClusterSize (int min_cluster_size)
368  {
369  min_pts_per_cluster_ = min_cluster_size;
370  }
371 
372  /** \brief Get the minimum number of points that a cluster needs to contain in order to be considered valid. */
373  inline int
375  {
376  return (min_pts_per_cluster_);
377  }
378 
379  /** \brief Set the maximum number of points that a cluster needs to contain in order to be considered valid.
380  * \param[in] max_cluster_size the maximum cluster size
381  */
382  inline void
383  setMaxClusterSize (int max_cluster_size)
384  {
385  max_pts_per_cluster_ = max_cluster_size;
386  }
387 
388  /** \brief Get the maximum number of points that a cluster needs to contain in order to be considered valid. */
389  inline int
391  {
392  return (max_pts_per_cluster_);
393  }
394 
395  /** \brief Cluster extraction in a PointCloud given by <setInputCloud (), setIndices ()>
396  * \param[out] clusters the resultant point clusters
397  */
398  void
399  extract (std::vector<PointIndices> &clusters);
400 
401  protected:
402  // Members derived from the base class
403  using BasePCLBase::input_;
404  using BasePCLBase::indices_;
407 
408  /** \brief A pointer to the spatial search object. */
410 
411  /** \brief The spatial cluster tolerance as a measure in the L2 Euclidean space. */
413 
414  /** \brief The minimum number of points that a cluster needs to contain in order to be considered valid (default = 1). */
416 
417  /** \brief The maximum number of points that a cluster needs to contain in order to be considered valid (default = MAXINT). */
419 
420  /** \brief Class getName method. */
421  virtual std::string getClassName () const { return ("EuclideanClusterExtraction"); }
422 
423  };
424 
425  /** \brief Sort clusters method (for std::sort).
426  * \ingroup segmentation
427  */
428  inline bool
430  {
431  return (a.indices.size () < b.indices.size ());
432  }
433 }
434 
435 #ifdef PCL_NO_PRECOMPILE
436 #include <pcl/segmentation/impl/extract_clusters.hpp>
437 #endif
pcl::search::Search
Generic search class.
Definition: search.h:74
pcl
Definition: convolution.h:46
pcl::EuclideanClusterExtraction::setMinClusterSize
void setMinClusterSize(int min_cluster_size)
Set the minimum number of points that a cluster needs to contain in order to be considered valid.
Definition: extract_clusters.h:367
pcl::EuclideanClusterExtraction::setClusterTolerance
void setClusterTolerance(double tolerance)
Set the spatial cluster tolerance as a measure in the L2 Euclidean space.
Definition: extract_clusters.h:351
pcl::EuclideanClusterExtraction::extract
void extract(std::vector< PointIndices > &clusters)
Cluster extraction in a PointCloud given by <setInputCloud (), setIndices ()>
Definition: extract_clusters.hpp:217
pcl::PCLBase::PointCloudConstPtr
typename PointCloud::ConstPtr PointCloudConstPtr
Definition: pcl_base.h:77
pcl::EuclideanClusterExtraction::getMinClusterSize
int getMinClusterSize() const
Get the minimum number of points that a cluster needs to contain in order to be considered valid.
Definition: extract_clusters.h:374
pcl::KdTree
KdTree represents the base spatial locator class for kd-tree implementations.
Definition: kdtree.h:56
pcl::PCLBase::input_
PointCloudConstPtr input_
The input point cloud dataset.
Definition: pcl_base.h:150
pcl::PCLBase::PointCloudPtr
typename PointCloud::Ptr PointCloudPtr
Definition: pcl_base.h:76
pcl::PointIndices::indices
Indices indices
Definition: PointIndices.h:23
pcl::PointIndices::header
::pcl::PCLHeader header
Definition: PointIndices.h:21
pcl::EuclideanClusterExtraction::setMaxClusterSize
void setMaxClusterSize(int max_cluster_size)
Set the maximum number of points that a cluster needs to contain in order to be considered valid.
Definition: extract_clusters.h:383
pcl::PCLBase
PCL base class.
Definition: pcl_base.h:72
pcl::PCLBase::PointIndicesConstPtr
PointIndices::ConstPtr PointIndicesConstPtr
Definition: pcl_base.h:80
pcl::PointCloud
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: distances.h:55
pcl::EuclideanClusterExtraction::KdTreePtr
typename KdTree::Ptr KdTreePtr
Definition: extract_clusters.h:316
pcl::EuclideanClusterExtraction::setSearchMethod
void setSearchMethod(const KdTreePtr &tree)
Provide a pointer to the search object.
Definition: extract_clusters.h:333
pcl::EuclideanClusterExtraction::EuclideanClusterExtraction
EuclideanClusterExtraction()
Empty constructor.
Definition: extract_clusters.h:323
pcl::EuclideanClusterExtraction
EuclideanClusterExtraction represents a segmentation class for cluster extraction in an Euclidean sen...
Definition: extract_clusters.h:306
pcl::PointIndices::ConstPtr
shared_ptr< const ::pcl::PointIndices > ConstPtr
Definition: PointIndices.h:16
pcl::KdTree::radiusSearch
virtual int radiusSearch(const PointT &p_q, double radius, std::vector< int > &k_indices, std::vector< float > &k_sqr_distances, unsigned int max_nn=0) const =0
Search for all the nearest neighbors of the query point in a given radius.
pcl::EuclideanClusterExtraction::max_pts_per_cluster_
int max_pts_per_cluster_
The maximum number of points that a cluster needs to contain in order to be considered valid (default...
Definition: extract_clusters.h:418
pcl::EuclideanClusterExtraction::min_pts_per_cluster_
int min_pts_per_cluster_
The minimum number of points that a cluster needs to contain in order to be considered valid (default...
Definition: extract_clusters.h:415
pcl::KdTree::getIndices
IndicesConstPtr getIndices() const
Get a pointer to the vector of indices used.
Definition: kdtree.h:95
pcl::KdTree::getInputCloud
PointCloudConstPtr getInputCloud() const
Get a pointer to the input point cloud dataset.
Definition: kdtree.h:102
pcl::search::Search::Ptr
shared_ptr< pcl::search::Search< PointT > > Ptr
Definition: search.h:81
pcl::EuclideanClusterExtraction::getSearchMethod
KdTreePtr getSearchMethod() const
Get a pointer to the search method used.
Definition: extract_clusters.h:342
pcl::PointIndices
Definition: PointIndices.h:13
pcl::PointCloud::header
pcl::PCLHeader header
The point cloud header.
Definition: point_cloud.h:408
pcl::PointIndices::Ptr
shared_ptr< ::pcl::PointIndices > Ptr
Definition: PointIndices.h:15
pcl::PointCloud::size
std::size_t size() const
Definition: point_cloud.h:459
pcl::PointCloud::Ptr
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:429
pcl::PCLBase::deinitCompute
bool deinitCompute()
This method should get called after finishing the actual computation.
Definition: pcl_base.hpp:171
pcl::PCLBase::indices_
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition: pcl_base.h:153
pcl::EuclideanClusterExtraction::tree_
KdTreePtr tree_
A pointer to the spatial search object.
Definition: extract_clusters.h:409
pcl::PointCloud::ConstPtr
shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:430
pcl::EuclideanClusterExtraction::getClusterTolerance
double getClusterTolerance() const
Get the spatial cluster tolerance as a measure in the L2 Euclidean space.
Definition: extract_clusters.h:358
pcl::PCLBase::PointIndicesPtr
PointIndices::Ptr PointIndicesPtr
Definition: pcl_base.h:79
pcl::comparePointClusters
bool comparePointClusters(const pcl::PointIndices &a, const pcl::PointIndices &b)
Sort clusters method (for std::sort).
Definition: extract_clusters.h:429
pcl::EuclideanClusterExtraction::cluster_tolerance_
double cluster_tolerance_
The spatial cluster tolerance as a measure in the L2 Euclidean space.
Definition: extract_clusters.h:412
pcl::EuclideanClusterExtraction::getMaxClusterSize
int getMaxClusterSize() const
Get the maximum number of points that a cluster needs to contain in order to be considered valid.
Definition: extract_clusters.h:390
pcl::PCLBase::initCompute
bool initCompute()
This method should get called before starting the actual computation.
Definition: pcl_base.hpp:138
pcl::PointCloud::push_back
void push_back(const PointT &pt)
Insert a new point in the cloud, at the end of the container.
Definition: point_cloud.h:566
pcl::extractEuclideanClusters
void extractEuclideanClusters(const PointCloud< PointT > &cloud, const typename search::Search< PointT >::Ptr &tree, float tolerance, std::vector< PointIndices > &clusters, unsigned int min_pts_per_cluster=1, unsigned int max_pts_per_cluster=(std::numeric_limits< int >::max)())
Decompose a region of space into clusters based on the Euclidean distance between points.
Definition: extract_clusters.hpp:45
pcl::EuclideanClusterExtraction::getClassName
virtual std::string getClassName() const
Class getName method.
Definition: extract_clusters.h:421