直接上代码:
pcl::PointCloud<pcl::PointXYZ>::Ptr add_cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);//建立树结构
tree->setInputCloud(cloud);
std::vector<pcl::PointIndices> cluster_indices;//被分割出来的点云团,(标号队列)
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;//创建欧式聚类对象
ec.setClusterTolerance(ui.lineEdit_ClusterTolerance->text().toDouble());//设置近邻搜索的搜索半径(单位为m)
ec.setMinClusterSize(ui.lineEdit_ClusterMinsize->text().toInt());//设置一个聚类需要的最小点数目
ec.setMaxClusterSize(ui.lineEdit_ClusterMaxsize->text().toInt());//设置一个聚类需要的最大点数目
ec.setSearchMethod(tree);//设置点云搜索机制
ec.setInputCloud(cloud);
ec.extract(cluster_indices);//从点云中提取聚类,并将点云团保存在cluster_indices中
//迭代访问点云索引cluster_indices,直至分割出所有聚类
typedef std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> cloudptrlist;//所有类别点云的向量
cloudptrlist ptrlist;
int j = 0;//定义变量j用于存储点云聚类名称
for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin(); it != cluster_indices.end(); it++)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZ>);//存放当前的点云聚类
for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); pit++)
{
cloud_cluster->points.push_back(cloud->points[*pit]);//将当前点云聚类中的点云索引存放到cloud_cluster中
}
cloud_cluster->width = cloud_cluster->points.size();
cloud_cluster->height = 1;
cloud_cluster->is_dense = true;
//保存点云文件
std::stringstream ss;
ss << "cloud_cluster_D" << j << ".pcd";//保存每一个聚类
pcl::PCDWriter writer;
writer.write<pcl::PointXYZ>(ss.str(), *cloud_cluster, false);
ptrlist.push_back(cloud_cluster);//关键的一句,所有的点云聚类都放到数组向量中去
j++;
}
//随机上色,注意区分点云的ID
for (int i = 0; i < ptrlist.size(); i++)
{
double r = 256 * rand() / (RAND_MAX + 1.0f);
double g = 256 * rand() / (RAND_MAX + 1.0f);
double b = 256 * rand() / (RAND_MAX + 1.0f);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> ::Ptr handler_tempt(new pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(r, g, b));
handler_tempt->setInputCloud(ptrlist[i]);
std::ostringstream oss;
oss << i;//不同的点云,赋予不同的ID
viewer->addPointCloud(ptrlist[i], *handler_tempt, "cluster" + oss.str());
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cluster" + oss.str());
}