C++ PCL欧式聚类:以指定点为起点并保存聚类索引
以下是完善后的C++代码,用于对点云ply文件进行欧式聚类,并将聚类索引结果保存到clusterIndices中:
for (int j = 0; j < clouds[i]->size(); j++)
{
// 以点j为中心进行聚类(xj, yj, zj),设置半径为r,进行欧式聚类,这里会得到骨架点个数的簇,所以也要创建指针容器
pcl::PointCloud<pcl::PointXYZ>::Ptr yq = yenn[j];
pcl::PointXYZ centroid1;
centroid1.x = clouds[i]->points[j].x;
centroid1.y = clouds[i]->points[j].y;
centroid1.z = clouds[i]->points[j].z;
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
ec.setClusterTolerance(r); // 设置聚类的半径
ec.setMinClusterSize(1); // 设置聚类的最小点数
ec.setMaxClusterSize(clouds[i]->size()); // 设置聚类的最大点数
ec.setSearchMethod(tree);
ec.setInputCloud(clouds[i]);
// 使用 setInputCloud 方法设置输入点云
ec.setInputCloud (clouds[i]);
// 使用 indices_ 成员变量指定要进行聚类的点云索引
pcl::PointIndices::Ptr yq_indices (new pcl::PointIndices);
yq_indices->indices.push_back(j);
ec.setIndices(yq_indices);
std::vector<pcl::PointIndices> clusterIndices;
ec.extract(clusterIndices);
// Output the indices of the clusters
for (const auto& indices : clusterIndices) // 遍历储存的所有类的索引
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cluster7(new pcl::PointCloud<pcl::PointXYZ>);
for (const auto& index : indices.indices) // 循环遍历一个类里所有点的索引将其加入点云指针
{
cluster7->push_back(clouds[i]->points[index]); // 将索引对应的点加入到这个类的指针中
}
yemm.push_back(cluster7); // 得到的一个类通过尾插法将其指针加入指针容器yenn,所以一片叶子的多个指针表示为clusters[i]
}
}
代码解释:
- 创建欧式聚类对象:
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec; - 设置聚类参数:
ec.setClusterTolerance(r);设置聚类半径ec.setMinClusterSize(1);设置最小聚类点数量ec.setMaxClusterSize(clouds[i]->size());设置最大聚类点数量ec.setSearchMethod(tree);设置搜索方法,可以使用kd-tree加速ec.setInputCloud(clouds[i]);设置输入点云ec.setIndices(yq_indices);设置聚类的起点
- 执行聚类:
ec.extract(clusterIndices);将聚类结果保存在clusterIndices中 - 遍历聚类结果: 代码中使用循环遍历
clusterIndices,并将每个聚类结果保存到新的点云对象中。
注意:
r是聚类半径,需要根据实际情况调整tree是预先建立的搜索树,可以为空,但使用搜索树可以提高效率yq_indices是一个pcl::PointIndices对象,用于指定要进行聚类的点云索引,这里我们只选择了点云中的第 j 个点作为起点。
原文地址: http://www.cveoy.top/t/topic/fEfq 著作权归作者所有。请勿转载和采集!