PCL:基于区域生长的点云分割——保存分割结果

Posted 没事就要敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PCL:基于区域生长的点云分割——保存分割结果相关的知识,希望对你有一定的参考价值。


欧式聚类保存聚类结果的方法类似。

1 区域生长分割原理

区域生长分割原理

2 代码实现

#include <pcl/io/pcd_io.h>
#include <pcl/search/search.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/segmentation/region_growing.h>

using namespace std;

typedef pcl::PointXYZRGB PointT;
typedef pcl::PointCloud<PointT> PointCloudT;

int main()

	//------------------------------- 加载点云 -------------------------------
	cout << "->正在加载点云..." << endl;
	PointCloudT::Ptr cloud(new PointCloudT);
	if (pcl::io::loadPCDFile("road.pcd", *cloud) < 0)
	
		PCL_ERROR("\\a点云文件不存在!\\n");
		system("pause");
		return (-1);
	
	cout << "->加载点的个数:" << cloud->points.size() << endl;
	//========================================================================

	//------------------------------- 法线估计 -------------------------------
	cout << "->正在估计点云法线..." << endl;
	pcl::NormalEstimation<PointT, pcl::Normal> ne;									//创建法线估计对象ne
	pcl::search::Search<PointT>::Ptr tree(new pcl::search::KdTree<PointT>);	//设置搜索方法
	pcl::PointCloud <pcl::Normal>::Ptr normals(new pcl::PointCloud <pcl::Normal>);			//存放法线
	ne.setSearchMethod(tree);
	ne.setInputCloud(cloud);
	ne.setKSearch(20);
	ne.compute(*normals);
	//========================================================================

	//------------------------------- 区域生长 -------------------------------
	cout << "->正在进行区域生长..." << endl;
	pcl::RegionGrowing<PointT, pcl::Normal> rg;	//创建区域生长分割对象
	rg.setMinClusterSize(50);							//设置满足聚类的最小点数
	rg.setMaxClusterSize(99999999);						//设置满足聚类的最大点数
	rg.setSearchMethod(tree);							//设置搜索方法
	rg.setNumberOfNeighbours(30);						//设置邻域搜索的点数
	rg.setInputCloud(cloud);							//设置输入点云
	rg.setInputNormals(normals);						//设置输入点云的法向量
	rg.setSmoothnessThreshold(3.0 / 180.0 * M_PI);		//设置平滑阈值,弧度,用于提取同一区域的点
	rg.setCurvatureThreshold(1);						//设置曲率阈值,如果两个点的法线偏差很小,则测试其曲率之间的差异。如果该值小于曲率阈值,则该算法将使用新添加的点继续簇的增长
	vector<pcl::PointIndices> clusters;					//聚类索引向量
	rg.extract(clusters);								//获取聚类结果,并保存到索引向量中

	cout << "->聚类个数为" << clusters.size() << endl;
	//========================================================================

	//---------------------- 为聚类点云添加颜色,并可视化 ----------------------
	PointCloudT::Ptr colored_cloud = rg.getColoredCloud();
	pcl::visualization::CloudViewer viewer("区域生长结果");
	viewer.showCloud(colored_cloud);
	while (!viewer.wasStopped())
	
	
	//========================================================================

	//---------------------------- 提取区域生长聚类 ---------------------------
	int count = 0;
	pcl::PCDWriter writer;
	for (vector<pcl::PointIndices>::const_iterator it = clusters.begin(); it != clusters.end(); ++it)
	
		PointCloudT::Ptr cloud_cluster(new PointCloudT);

		for (vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); pit++)
			cloud_cluster->points.push_back(colored_cloud->points[*pit]);
		cloud_cluster->width = cloud_cluster->points.size();
		cloud_cluster->height = 1;
		cloud_cluster->is_dense = true;

		stringstream ss;
		ss << "cluster_" << count + 1 << ".pcd";
		writer.write(ss.str(), *cloud_cluster, true);
		cout << ss.str() << "点数:" << cloud_cluster->points.size() << endl;

		count++;
	
	//========================================================================

	return (0);


输出结果:

->正在加载点云...
->加载点的个数:200293
->正在估计点云法线...
->正在进行区域生长...
->聚类个数为31
cluster_1.pcd点数:10095
cluster_2.pcd点数:95928
cluster_3.pcd点数:13204
cluster_4.pcd点数:11475
cluster_5.pcd点数:6599
cluster_6.pcd点数:342
cluster_7.pcd点数:1634
cluster_8.pcd点数:557
cluster_9.pcd点数:80
cluster_10.pcd点数:2455
cluster_11.pcd点数:108
cluster_12.pcd点数:253
cluster_13.pcd点数:66
cluster_14.pcd点数:196
cluster_15.pcd点数:971
cluster_16.pcd点数:52
cluster_17.pcd点数:62
cluster_18.pcd点数:61
cluster_19.pcd点数:155
cluster_20.pcd点数:58
cluster_21.pcd点数:96
cluster_22.pcd点数:65
cluster_23.pcd点数:58
cluster_24.pcd点数:64
cluster_25.pcd点数:84
cluster_26.pcd点数:90
cluster_27.pcd点数:64
cluster_28.pcd点数:69
cluster_29.pcd点数:114
cluster_30.pcd点数:59
cluster_31.pcd点数:67

3 结果展示

不满足聚类条件的,显示为红色(主要为树木点云)

将保存的分割结果导入到CloudCompare中,结果如下:

4 相关链接

PCL点云数据处理基础目录

PCL:基于区域生长的点云分割原理与实现

以上是关于PCL:基于区域生长的点云分割——保存分割结果的主要内容,如果未能解决你的问题,请参考以下文章

PCL—点云分割(最小割算法)

PCL:基于颜色的区域生长分割

Open3D 区域生长分割(python详细过程版)

3D,点云分割,不要割个寂寞

3D,点云分割,不要割个寂寞

基于区域增长(RegionGrowing)的分割算法——参照pcl源码