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