PCL点云焊点提取

滚回来更新一篇文章,和各位交流一下
待处理点云:
数量级:百万
类型:零部件
描述:弯曲表面上有一些凸起在上面,需要提取凸起和平面接触的一圈点云,作为焊接的加工点

在这里插入图片描述

参考:

https://zhuanlan.zhihu.com/p/32111069

其实这篇文章也算是全面了,思路和他的差不多,只是算法不太一样,主要是前处理点云数据这里不太一样
首先是体素栅格滤波,待处理点云数据不均匀,且存在点云重影的问题,拟合算法效果不太好:

体素栅格:

	pcl::VoxelGrid<pcl::PointXYZ> sor;
	sor.setInputCloud(cloudA);
	sor.setLeafSize(1.2f, 1.2f, 1.2f);//设置滤波时创建的体素大小为1.2cm立方体
	sor.filter(*cloud_filtered);

高斯:

pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>); //kdtree搜索
	pcl::PointCloud<pcl::PointNormal> mls_points;
	pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls;
		mls.setComputeNormals(true);// 最小二乘计算中
	mls.setInputCloud(cloud);
	mls.setPolynomialFit(true);  //多项式拟合提高精度,
	mls.setPolynomialOrder(2);//2次多项式
	mls.setSearchMethod(tree);
	mls.setSearchRadius(0.05);//半径
	mls.setSqrGaussParam(10);

前处理最好能处理点云达到需求,保持轮廓的情况下点云数量级越小越好

正式处理:
和知乎文章一样
1.导入点云:

//导入pcd

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloudA(new pcl::PointCloud<pcl::PointXYZ>);

	if (pcl::io::loadPCDFile<pcl::PointXYZ>("xx.pcd", *cloudA) == -1)
	{
		PCL_ERROR("未导入点云\n");

		return -1;
	}

2.法线计算:

//先计算法线


	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;

	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());

	ne.setSearchMethod(tree);

	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);

	ne.setRadiusSearch(1);//搜索半径1cm

	ne.compute(*normals);

	pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);

	pcl::concatenateFields(*cloudA, *normals, *cloud_with_normals);

	

3.提取平面:采用RANSAC提取平面

     setOptimizeCoefficients(true);

	seg.setModelType(pcl::SACMODEL_NORMAL_PLANE); 

	seg.setNormalDistanceWeight(0.1);//法线权重系数0.1

	seg.setMethodType(pcl::SAC_RANSAC);

	seg.setMaxIterations(1000); //迭代的次数1000

	seg.setDistanceThreshold(0.5); //内点到模型的距离最大0.5

4.边界提取



	normEst.setKSearch(9);  //法向估计的点数

	normEst.compute(*normals1);

	est.setInputCloud(cloud_filtered);

	est.setInputNormals(normals1);

	est.setSearchMethod(tree1);

	est.setKSearch(20);  

	est.compute(boundaries);

到这里已经有效果了:
z在这里插入图片描述
知乎文章也是到这一步:
在这里插入图片描述
这位大神说后面需要去掉边框,和我的问题一样,大神不说那我来说拉:

直通滤波:

pcl::PassThrough<pcl::PointXYZ> pass_x;
	pass_x.setInputCloud(BoundPoints);
	pass_x.setFilterFieldName("x");
	pass_x.setFilterLimits(min.x + 10, max.x - 20);
	pass_x.filter(*cloud_filtered_x);

最终效果:
在这里插入图片描述
搞定,下次还不知道什么时候有时间来更新啊

展开阅读全文
©️2020 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值