38 #ifndef PCL_SEGMENTATION_IMPL_EXTRACT_CLUSTERS_H_
39 #define PCL_SEGMENTATION_IMPL_EXTRACT_CLUSTERS_H_
41 #include <pcl/segmentation/extract_clusters.h>
42 #include <pcl/search/organized.h>
45 template <
typename Po
intT>
void
48 float tolerance, std::vector<PointIndices> &clusters,
49 unsigned int min_pts_per_cluster,
50 unsigned int max_pts_per_cluster)
54 PCL_ERROR(
"[pcl::extractEuclideanClusters] Tree built for a different point cloud "
55 "dataset (%zu) than the input cloud (%zu)!\n",
57 static_cast<std::size_t
>(cloud.
size()));
63 std::vector<bool> processed (cloud.
size (),
false);
66 std::vector<float> nn_distances;
68 for (
int i = 0; i < static_cast<int> (cloud.
size ()); ++i)
75 seed_queue.push_back (i);
79 while (sq_idx <
static_cast<int> (seed_queue.size ()))
82 if (!tree->
radiusSearch (seed_queue[sq_idx], tolerance, nn_indices, nn_distances))
88 for (std::size_t j = nn_start_idx; j < nn_indices.size (); ++j)
90 if (nn_indices[j] == UNAVAILABLE || processed[nn_indices[j]])
94 seed_queue.push_back (nn_indices[j]);
95 processed[nn_indices[j]] =
true;
102 if (seed_queue.size () >= min_pts_per_cluster && seed_queue.size () <= max_pts_per_cluster)
105 r.
indices.resize (seed_queue.size ());
106 for (std::size_t j = 0; j < seed_queue.size (); ++j)
113 clusters.push_back (r);
117 PCL_DEBUG(
"[pcl::extractEuclideanClusters] This cluster has %zu points, which is not between %u and %u points, so it is not a final cluster\n",
118 seed_queue.size (), min_pts_per_cluster, max_pts_per_cluster);
124 template <
typename Po
intT>
void
128 float tolerance, std::vector<PointIndices> &clusters,
129 unsigned int min_pts_per_cluster,
130 unsigned int max_pts_per_cluster)
135 PCL_ERROR(
"[pcl::extractEuclideanClusters] Tree built for a different point cloud "
136 "dataset (%zu) than the input cloud (%zu)!\n",
138 static_cast<std::size_t
>(cloud.
size()));
141 if (tree->
getIndices()->size() != indices.size()) {
142 PCL_ERROR(
"[pcl::extractEuclideanClusters] Tree built for a different set of "
143 "indices (%zu) than the input set (%zu)!\n",
144 static_cast<std::size_t
>(tree->
getIndices()->size()),
152 std::vector<bool> processed (cloud.
size (),
false);
155 std::vector<float> nn_distances;
157 for (
const auto &index : indices)
159 if (processed[index])
164 seed_queue.push_back (index);
166 processed[index] =
true;
168 while (sq_idx <
static_cast<int> (seed_queue.size ()))
171 int ret = tree->
radiusSearch (cloud[seed_queue[sq_idx]], tolerance, nn_indices, nn_distances);
174 PCL_ERROR(
"[pcl::extractEuclideanClusters] Received error code -1 from radiusSearch\n");
183 for (std::size_t j = nn_start_idx; j < nn_indices.size (); ++j)
185 if (nn_indices[j] == UNAVAILABLE || processed[nn_indices[j]])
189 seed_queue.push_back (nn_indices[j]);
190 processed[nn_indices[j]] =
true;
197 if (seed_queue.size () >= min_pts_per_cluster && seed_queue.size () <= max_pts_per_cluster)
200 r.
indices.resize (seed_queue.size ());
201 for (std::size_t j = 0; j < seed_queue.size (); ++j)
209 clusters.push_back (r);
213 PCL_DEBUG(
"[pcl::extractEuclideanClusters] This cluster has %zu points, which is not between %u and %u points, so it is not a final cluster\n",
214 seed_queue.size (), min_pts_per_cluster, max_pts_per_cluster);
223 template <
typename Po
intT>
void
226 if (!initCompute () ||
227 (input_ && input_->points.empty ()) ||
228 (indices_ && indices_->empty ()))
237 if (input_->isOrganized ())
244 tree_->setInputCloud (input_, indices_);
245 extractEuclideanClusters (*input_, *indices_, tree_,
static_cast<float> (cluster_tolerance_), clusters, min_pts_per_cluster_, max_pts_per_cluster_);
256 #define PCL_INSTANTIATE_EuclideanClusterExtraction(T) template class PCL_EXPORTS pcl::EuclideanClusterExtraction<T>;
257 #define PCL_INSTANTIATE_extractEuclideanClusters(T) template void PCL_EXPORTS pcl::extractEuclideanClusters<T>(const pcl::PointCloud<T> &, const typename pcl::search::Search<T>::Ptr &, float , std::vector<pcl::PointIndices> &, unsigned int, unsigned int);
258 #define PCL_INSTANTIATE_extractEuclideanClusters_indices(T) template void PCL_EXPORTS pcl::extractEuclideanClusters<T>(const pcl::PointCloud<T> &, const pcl::Indices &, const typename pcl::search::Search<T>::Ptr &, float , std::vector<pcl::PointIndices> &, unsigned int, unsigned int);
PointCloud represents the base class in PCL for storing collections of 3D points.
pcl::PCLHeader header
The point cloud header.
search::KdTree is a wrapper class which inherits the pcl::KdTree class for performing search function...
OrganizedNeighbor is a class for optimized nearest neighbor search in organized projectable point clo...
virtual bool getSortedResults()
Gets whether the results should be sorted (ascending in the distance) or not Otherwise the results ma...
virtual IndicesConstPtr getIndices() const
Get a pointer to the vector of indices used.
shared_ptr< pcl::search::Search< PointT > > Ptr
virtual PointCloudConstPtr getInputCloud() const
Get a pointer to the input point cloud dataset.
virtual int radiusSearch(const PointT &point, double radius, Indices &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.
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.
bool comparePointClusters(const pcl::PointIndices &a, const pcl::PointIndices &b)
Sort clusters method (for std::sort).
IndicesAllocator<> Indices
Type used for indices in PCL.