当前位置:   article > 正文

PCL学习笔记(42)——点云区域生长RegionGrowing分割算法_点云区域生长时间

点云区域生长时间

源码

#include <iostream>
#include <vector>
#include <pcl/point_types.h>
#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/filters/passthrough.h>
#include <pcl/segmentation/region_growing.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>
#include <windows.h>
#include <stdio.h>
#include <psapi.h>

void simpleVis(pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)
{
	//创建3D窗口并添加点云
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0);
	viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
	viewer->addCoordinateSystem(1.0);
	viewer->initCameraParameters();
	viewer->spin();
}

using namespace pcl::console;
int main (int argc, char** argv)
{

	if(argc<2)
	{
		std::cout<<".exe xx.pcd -kn 50 -bc 0 -fc 10.0 -nc 0 -st 30 -ct 0.05"<<endl;

		return 0;
	}//如果输入参数小于1个,输出提示
	time_t start,end,diff[5],option;
	start = time(0); 
	int KN_normal=50; //设置默认输入参数
	bool Bool_Cuting=false;//设置默认输入参数
	float far_cuting=10,near_cuting=0,SmoothnessThreshold=30.0,CurvatureThreshold=0.05;//设置默认输入参数
	parse_argument (argc, argv, "-kn", KN_normal);
	parse_argument (argc, argv, "-bc", Bool_Cuting);
	parse_argument (argc, argv, "-fc", far_cuting);
	parse_argument (argc, argv, "-nc", near_cuting);
	parse_argument (argc, argv, "-st", SmoothnessThreshold);
	parse_argument (argc, argv, "-ct", CurvatureThreshold);//设置输入参数方式
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
	if ( pcl::io::loadPCDFile <pcl::PointXYZ> (argv[1], *cloud) == -1)
	{
		std::cout << "Cloud reading failed." << std::endl;
		return (-1);
	}// 加载输入点云数据

	simpleVis(cloud);

	end = time(0); 
	diff[0] = difftime (end, start); 
	PCL_INFO ("\Loading pcd file takes(seconds): %d\n", diff[0]); 
	//Noraml estimation step(1 parameter)
	pcl::search::Search<pcl::PointXYZ>::Ptr tree = boost::shared_ptr<pcl::search::Search<pcl::PointXYZ> > (new pcl::search::KdTree<pcl::PointXYZ>);//创建一个指向kd树搜索对象的共享指针
	pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>);
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimator;//创建法线估计对象
	normal_estimator.setSearchMethod (tree);//设置搜索方法
	normal_estimator.setInputCloud (cloud);//设置法线估计对象输入点集
	normal_estimator.setKSearch (KN_normal);// 设置用于法向量估计的k近邻数目
	normal_estimator.compute (*normals);//计算并输出法向量
	end = time(0); 
	diff[1] = difftime (end, start)-diff[0]; 
	PCL_INFO ("\Estimating normal takes(seconds): %d\n", diff[1]); 
	//optional step: cutting the part are far from the orignal point in Z direction.2 parameters
	pcl::IndicesPtr indices (new std::vector <int>);//创建一组索引
	if(Bool_Cuting)//判断是否需要直通滤波
	{

		pcl::PassThrough<pcl::PointXYZ> pass;//设置直通滤波器对象
		pass.setInputCloud (cloud);//设置输入点云
		pass.setFilterFieldName ("z");//设置指定过滤的维度
		pass.setFilterLimits (near_cuting, far_cuting);//设置指定纬度过滤的范围
		pass.filter (*indices);//执行滤波,保存滤波结果在上述索引中
	}
	//simpleVis(cloud);

	// 区域生长算法的5个参数
	pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;//创建区域生长分割对象
	reg.setMinClusterSize (50);//设置一个聚类需要的最小点数
	reg.setMaxClusterSize (1000000);//设置一个聚类需要的最大点数
	reg.setSearchMethod (tree);//设置搜索方法
	reg.setNumberOfNeighbours (30);//设置搜索的临近点数目
	reg.setInputCloud (cloud);//设置输入点云
	if(Bool_Cuting)reg.setIndices (indices);//通过输入参数设置,确定是否输入点云索引
	reg.setInputNormals (normals);//设置输入点云的法向量
	reg.setSmoothnessThreshold (SmoothnessThreshold / 180.0 * M_PI);//设置平滑阈值
	reg.setCurvatureThreshold (CurvatureThreshold);//设置曲率阈值

	std::vector <pcl::PointIndices> clusters;
	reg.extract (clusters);//获取聚类的结果,分割结果保存在点云索引的向量中。
	end = time(0); 
	diff[2] = difftime (end, start)-diff[0]-diff[1]; 
	PCL_INFO ("\Region growing takes(seconds): %d\n", diff[2]); 

	std::cout << "Number of clusters is equal to " << clusters.size () << std::endl;//输出聚类的数量
	std::cout << "First cluster has " << clusters[0].indices.size () << " points." << endl;//输出第一个聚类的数量
	std::cout << "These are the indices of the points of the initial" <<
		std::endl << "cloud that belong to the first cluster:" << std::endl;
	/* int counter = 0;
	while (counter < clusters[0].indices.size ())
	{
	std::cout << clusters[0].indices[counter] << ", ";
	counter++;
	if (counter % 10 == 0)
	std::cout << std::endl;
	}
	std::cout << std::endl;
	*/
	pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud ();
	pcl::visualization::CloudViewer viewer ("点云库PCL学习教程第二版-区域增长分割方法");
	viewer.showCloud(colored_cloud);
	while (!viewer.wasStopped ())
	{
	}//进行可视化

	return (0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • step 1 加载数据

在这里插入图片描述

  • step 2 计算法向量和直通滤波用于区域成长

  • step 3 初始化区域生长模型

	// 区域生长算法的5个参数
	pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;//创建区域生长分割对象
	reg.setMinClusterSize (50);//设置一个聚类需要的最小点数
	reg.setMaxClusterSize (1000000);//设置一个聚类需要的最大点数
	reg.setSearchMethod (tree);//设置搜索方法
	reg.setNumberOfNeighbours (30);//设置搜索的临近点数目
	reg.setInputCloud (cloud);//设置输入点云
	if(Bool_Cuting)reg.setIndices (indices);//通过输入参数设置,确定是否输入点云索引
	reg.setInputNormals (normals);//设置输入点云的法向量
	reg.setSmoothnessThreshold (SmoothnessThreshold / 180.0 * M_PI);//设置平滑阈值
	reg.setCurvatureThreshold (CurvatureThreshold);//设置曲率阈值
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • step 4 获取分割结果并显示
	std::vector <pcl::PointIndices> clusters;
	reg.extract (clusters);//获取聚类的结果,分割结果保存在点云索引的向量中。
	pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud ();
	pcl::visualization::CloudViewer viewer ("点云库PCL学习教程第二版-区域增长分割方法");
	viewer.showCloud(colored_cloud);
  • 1
  • 2
  • 3
  • 4
  • 5

这里的colored_cloud = reg.getColoredCloud ()应该是封装好的方法,直接给聚类的结果用不同的颜色表示,使用clusters也可以逐个显示
在这里插入图片描述

基于区域生长RGB算法源码

#include <iostream>
#include <vector>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/search/search.h>
#include <pcl/search/kdtree.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/filters/passthrough.h>
#include <pcl/segmentation/region_growing_rgb.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>
#include <pcl/features/normal_3d.h>
using namespace pcl::console;
int main (int argc, char** argv)
{

	if(argc<2)
	{
		std::cout<<".exe xx.pcd -b_n 0 -kn 50 -st_n 30 -ct_n 0.05 -bc 0 -fc 10 -nc 0 -dt 10 -ct 6 -rt 5 -mt 600" <<endl;

		return 0;
	}
	time_t start,end,diff[5],option;
	start = time(0); 
	bool Bool_Cuting=false,b_n=false;
	int MinClusterSize=600,KN_normal=50;
	float far_cuting=10,near_cuting=0,DistanceThreshold=10.0,ColorThreshold=6,RegionColorThreshold=5,SmoothnessThreshold=30.0,CurvatureThreshold=0.05;

	parse_argument (argc, argv, "-b_n", b_n);
	parse_argument (argc, argv, "-kn", KN_normal);
	parse_argument (argc, argv, "-st_n", SmoothnessThreshold);
	parse_argument (argc, argv, "-ct_n", CurvatureThreshold);


	parse_argument (argc, argv, "-bc", Bool_Cuting);
	parse_argument (argc, argv, "-fc", far_cuting);
	parse_argument (argc, argv, "-nc", near_cuting);
	
	parse_argument (argc, argv, "-dt", DistanceThreshold);
	parse_argument (argc, argv, "-ct", ColorThreshold);
	parse_argument (argc, argv, "-rt", RegionColorThreshold);
	parse_argument (argc, argv, "-mt", MinClusterSize);



	//frist step load the point cloud
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
	if ( pcl::io::loadPCDFile <pcl::PointXYZRGB> (argv[1], *cloud) == -1)
	{
		std::cout << "Cloud reading failed." << std::endl;
		return (-1);
	}
	end = time(0); 
	diff[0] = difftime (end, start); 
	PCL_INFO ("\Loading pcd file takes(seconds): %d\n", diff[0]); 
	pcl::search::Search <pcl::PointXYZRGB>::Ptr tree = boost::shared_ptr<pcl::search::Search<pcl::PointXYZRGB> > (new pcl::search::KdTree<pcl::PointXYZRGB>);

	//Noraml estimation step(1 parameter)
	pcl::search::Search<pcl::PointXYZRGB>::Ptr tree1 = boost::shared_ptr<pcl::search::Search<pcl::PointXYZRGB> > (new pcl::search::KdTree<pcl::PointXYZRGB>);
	pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>);
	pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal> normal_estimator;
	normal_estimator.setSearchMethod (tree);
	normal_estimator.setInputCloud (cloud);
	normal_estimator.setKSearch (KN_normal);
	normal_estimator.compute (*normals);
	end = time(0); 
	diff[1] = difftime (end, start)-diff[0]; 
	PCL_INFO ("\Estimating normal takes(seconds): %d\n", diff[1]); 
	//Optional step: cutting away the clutter scene too far away from camera
	pcl::IndicesPtr indices (new std::vector <int>);
	if(Bool_Cuting)//是否通过z轴范围对待处理数据进行裁剪
	{

		pcl::PassThrough<pcl::PointXYZRGB> pass;
		pass.setInputCloud (cloud);
		pass.setFilterFieldName ("z");
		pass.setFilterLimits (near_cuting, far_cuting);
		pass.filter (*indices);
	}
	// Region growing RGB 
	pcl::RegionGrowingRGB<pcl::PointXYZRGB> reg;
	reg.setInputCloud (cloud);
	if(Bool_Cuting)reg.setIndices (indices);
	reg.setSearchMethod (tree);
	reg.setDistanceThreshold (DistanceThreshold);
	reg.setPointColorThreshold (ColorThreshold);
	reg.setRegionColorThreshold (RegionColorThreshold);
	reg.setMinClusterSize (MinClusterSize);
	if(b_n)
	{
		reg.setSmoothModeFlag(true);
		reg.setCurvatureTestFlag(true);

		reg.setInputNormals (normals);
		reg.setSmoothnessThreshold (SmoothnessThreshold / 180.0 * M_PI);
		reg.setCurvatureThreshold (CurvatureThreshold);
	}
	std::vector <pcl::PointIndices> clusters;
	reg.extract (clusters);
	end = time(0); 
	diff[2] = difftime (end, start)-diff[0]-diff[1]; 
	PCL_INFO ("\RGB region growing takes(seconds): %d\n", diff[2]); 

	pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud ();
	pcl::visualization::CloudViewer viewer ("点云库PCL学习教程第二版实例-基于颜色的区域生长算法实现点云分割");
	viewer.showCloud (colored_cloud);
	while (!viewer.wasStopped ())
	{
		boost::this_thread::sleep (boost::posix_time::microseconds (100));
	}

	return (0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

在这里插入图片描述

拓展

另推荐一门深蓝学院开设讲解三维点云处理的线上课程,可以对整体框架的细节理解和运用都能起到很好的帮助:

链接:三维点云处理

技术交流可以去我主页左侧扫码进群

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/228955
推荐阅读
相关标签
  

闽ICP备14008679号