点云的聚类算法
https://blog.csdn.net/luolaihua2018/article/details/120184539
欧式聚类流程
点云欧式聚类算法流程
(1)点云读入;
(2)体素化下采样(方便处理);
(3)去离散点;
(4)RANSAC算法检测平面,并剔除平面点云;
(5)欧式聚类;
(6)结果的输出和可视化;
代码(只输出点最多的一个类)
pcl::search::KdTree<PointType>::Ptr tree(new pcl::search::KdTree<PointType>);
tree->setInputCloud(obj_cloud);//创建点云索引向量,用于存储实际的点云信息
//用于存储聚类点的容器
vector<pcl::PointIndices> cluster_indices;
pcl::EuclideanClusterExtraction<PointType> ec;
ec.setClusterTolerance(0.02); // 设置近邻搜索的搜索半径为2cm
ec.setMinClusterSize(1000);//设置一个聚类需要的最少点数目为100
ec.setMaxClusterSize(10000);//设置一个聚类需要的最大点数目为25000
ec.setSearchMethod(tree);//设置点云的搜索机制
ec.setInputCloud(obj_cloud);
ec.extract(cluster_indices);//从点云中提取聚类,并将点云索引保存在cluster_indices中
cloud_cluster = this->best_obj(cluster_indices,obj_cloud);
PointCloud<PointType>::Ptr pointcloud_seg::best_obj(const vector<pcl::PointIndices>& cluster_indices,const pcl::PointCloud<PointType>::Ptr &msg)
{
int index=cluster_indices.size();
pcl::PointCloud<PointType>::Ptr cloud_cluster(new pcl::PointCloud<PointType>);
int clu=0;
if(index ==0)
{
cout<<"There are no object in this pointcloud!"<<endl;
return msg;
}
int maxmum=cluster_indices[0].indices.size();
for(int i=0;i<index;i++)
{
if(cluster_indices[i].indices.size()>maxmum)
{
maxmum=cluster_indices[i].indices.size();
clu = i;
}
}
pcl::PointIndices max=cluster_indices[clu];
for (vector<int>::const_iterator pit = max.indices.begin(); pit != max.indices.end(); pit++) {
cloud_cluster->points.push_back(msg->points[*pit]);
cloud_cluster->header = msg->header;
cloud_cluster->width = cloud_cluster->points.size();
cloud_cluster->height = 1;
cloud_cluster->is_dense = true;
}
std::cout << "PointCloud representing the Cluster: " << cloud_cluster->size() << " data points."<< std::endl;
return cloud_cluster;
}