ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

PCL点云平面分割

2020-12-24 09:58:59  阅读:568  来源: 互联网

标签:分割 PCL color points pcl 点云 PointCloud Ptr cloud


PCL点云平面分割


多平面分割方法封装

/** \brief 多平面分割
* \param[in] cloud_in 待分割点云
* \param[in] maxiter 最大迭代次数
* \param[in] dist 判断是否为平面内点的距离阈值
* \param[in] proportion 非平面点所占点云比例,[0,1]之间取值
* \param[out] out_plane_vect 分割后的平面模型点云集合
* \return 0成功,-1失败
*/
int g_multPlaneSeg(pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud_in, int maxiter, double dist,  float proportion, std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& out_plane_vect)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloudXYZ(new pcl::PointCloud<pcl::PointXYZ>());
	pcl::copyPointCloud(*cloud_in, *cloudXYZ);
	std::vector<int> mapping;
	pcl::removeNaNFromPointCloud(*cloudXYZ, *cloudXYZ, mapping);

	out_plane_vect.clear();
	//平面提取,获取平面方程
	pcl::SACSegmentation<pcl::PointXYZ> seg;
    seg.setModelType(pcl::SACMODEL_PLANE);//平面模型		

	seg.setOptimizeCoefficients(true); //设置对估计的模型参数进行优化处理
	seg.setMethodType(pcl::SAC_RANSAC); // 设置用哪个随机参数估计方法,分割方法:随机采样法

	seg.setMaxIterations(maxiter);//设置最大迭代次数 
	seg.setDistanceThreshold(dist);//设置判断是否为模型内点的距离阈值

	size_t nr_points = cloudXYZ->points.size();

	while (cloudXYZ->points.size() > proportion * nr_points)
	{
		pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
		pcl::PointIndices::Ptr inliersIndices(new pcl::PointIndices());

		seg.setInputCloud(cloudXYZ);
		seg.segment(*inliersIndices, *coefficients);
		if (inliersIndices->indices.size() == 0)//没有提取出点
		{
			break;
		}
		pcl::PointCloud<pcl::PointXYZ>::Ptr  cloud_inliers(new pcl::PointCloud<pcl::PointXYZ>);
		pcl::PointCloud<pcl::PointXYZ>::Ptr  cloud_outliers(new pcl::PointCloud<pcl::PointXYZ>);
		pcl::ExtractIndices<pcl::PointXYZ> extract; //创建点云提取对象
		extract.setInputCloud(cloudXYZ);//设置输入点云
		extract.setIndices(inliersIndices);
		extract.setNegative(false); //设置提取内点而非外点
		extract.filter(*cloud_inliers);//提取输出存储到cloud_inliers
		extract.setNegative(true);//提取外点
		extract.filter(*cloud_outliers);
		*cloudXYZ = *cloud_outliers;
		out_plane_vect.push_back(cloud_inliers);
	}
	if (out_plane_vect.size() == 0)
	{
		return -1;
	}
	return 0;
}

调用如下


int main()
{
	std::string filename_ = "bunny.pcd";

	pcl::console::TicToc timecal;
	timecal.tic();
	pcl::PointCloud<pcl::PointXYZ>::Ptr model(new pcl::PointCloud<pcl::PointXYZ>());
	if (pcl::io::loadPCDFile(filename_, *model) < 0)
	{
		std::cout << "Error loading model cloud." << std::endl;
		return (-1);
	}
	std::cout << "加载点云成功.耗时:" << timecal.toc() << "ms" << std::endl;
	//速度慢降采样
	pcl::VoxelGrid<pcl::PointXYZ> vg;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
	vg.setInputCloud(model);
	vg.setLeafSize(0.005f, 0.005f, 0.005f);
	vg.filter(*cloud_filtered);

	timecal.tic();
	std::cout << "开始提取平面" << std::endl;
	std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> outPlaneVect;
	g_multPlaneSeg(cloud_filtered, 10000, 0.02, 0.2, outPlaneVect);
	std::cout << "结束提取平面" << std::endl;
	std::cout << "提取平面个数:" << outPlaneVect.size() <<"。耗时:"<< timecal.toc() << "ms" << std::endl;


	// visualization
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Viewer"));
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_color(new pcl::PointCloud<pcl::PointXYZRGB>());
	srand(time(nullptr));
	std::vector<unsigned char> color;
	for (size_t i = 0; i < outPlaneVect.size(); i++)
	{
		color.push_back(static_cast<unsigned char>(rand() % 256));
		color.push_back(static_cast<unsigned char>(rand() % 256));
		color.push_back(static_cast<unsigned char>(rand() % 256));
	}
	int color_index(0);
	for (size_t i = 0; i < outPlaneVect.size(); i++)
	{
		for (size_t j = 0; j < outPlaneVect[i]->points.size(); j++)
		{
			if (pcl_isnan(outPlaneVect[i]->points[j].x))
			{
				continue;
			}
			pcl::PointXYZRGB n_points;
			n_points.x = outPlaneVect[i]->points[j].x;
			n_points.y = outPlaneVect[i]->points[j].y;
			n_points.z = outPlaneVect[i]->points[j].z;
			n_points.r = color[3 * color_index];
			n_points.g = color[3 * color_index + 1];
			n_points.b = color[3 * color_index + 2];
			cloud_color->push_back(n_points);
		}
		color_index++;
	}
	viewer->addPointCloud(cloud_color);
	viewer->spin();

	system("pause");
	return 0;
}

标签:分割,PCL,color,points,pcl,点云,PointCloud,Ptr,cloud
来源: https://blog.csdn.net/Joker_mw/article/details/111604610

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有