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);

最終效果:
在這裏插入圖片描述
搞定,下次還不知道什麼時候有時間來更新啊

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章