PCL 拟合圆锥(以RANSAC为例)(SampleConsensus_Cone)

   PCL专栏目录及须知

以RANSAC为例。如果要用其他采样一致性算法,就只需要变换代码块中的这部分代码就可以。

可使用的其他采样一致性算法类型使用方法及算法的原理解释

1.参数介绍

球体的Eigen::VectorXf参数为7。分别是:

圆锥体顶点的x坐标;圆锥体顶点的y坐标;圆锥体顶点的z坐标;

圆锥体轴方向的x坐标;圆锥体轴方向的y坐标;圆锥体轴方向的z坐标;

圆锥体的张开角度;

2.完整代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d.h>  
#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_cone.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

int main()
{
	/****************拟合圆锥********************/
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);			// 源点云
	pcl::io::loadPCDFile("D:/code/csdn/data/rabbit.pcd", *cloud);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloudInliers(new pcl::PointCloud<pcl::PointXYZ>);			// 拟合出的内点

	/****************拟合圆锥********************/
	// 计算法线
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
	n.setInputCloud(cloud);
	n.setSearchMethod(tree);
	n.setKSearch(50);		// K近邻搜索个数
	n.compute(*normals);

	pcl::SampleConsensusModelCone<pcl::PointXYZ, pcl::Normal >::Ptr model(new pcl::SampleConsensusModelCone<pcl::PointXYZ, pcl::Normal >(cloud));
	model->setInputNormals(normals);
	pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model);	// 定义RANSAC算法对象
	ransac.setDistanceThreshold(0.01);							// 设置距离阈值
	ransac.setMaxIterations(500);								// 设置最大迭代次数
	ransac.computeModel();
	Eigen::VectorXf coeff;
	ransac.getModelCoefficients(coeff);							// 参数
	std::vector<int> ranSacInliers;                                                 // 获取属于拟合出的内点
	ransac.getInliers(ranSacInliers);
	pcl::copyPointCloud(*cloud, ranSacInliers, *cloudInliers);

	std::cout << "圆锥体顶点的x坐标为:" << coeff[0] << "\n圆锥体顶点的y坐标为:" << coeff[1] << "\n圆锥体顶点的z坐标为:" << coeff[2]
		<< "\n圆锥体轴方向的x坐标为:" << coeff[3] << "\n圆锥体轴方向的y坐标为:" << coeff[4] << "\n圆锥体轴方向的z坐标为:" << coeff[5]
		<< "\n圆锥体的张开角度:" << coeff[6]
		<< std::endl;

	/****************展示********************/
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("ransac"));
	viewer->addPointCloud<pcl::PointXYZ>(cloud, "cloud");
	viewer->addPointCloud<pcl::PointXYZ>(cloudInliers, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(cloudInliers, 255, 0, 0), "cloudInliers");

	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

	return (0);
}

3.结果代码

打印:

结果可视化:

在一堆点云中滤除表面呈圆锥状的物体,通常可以通过以下步骤实现: 1. **点云预处理**: - **降噪**:使用滤波算法(如均值滤波、高斯滤波)去除点云中的噪声。 - **下采样**:使用体素网格下采样(Voxel Grid Downsampling)减少点云数据量,提高处理速度。 2. **法线估计**: - 计算每个点的法线方向。可以使用PCL(Point Cloud Library)中的法线估计模块来实现。 3. **特征提取**: - 提取点云的局部特征,如曲率、法线方向等。 - 使用RANSAC(Random Sample Consensus)算法拟合圆锥模型。 4. **圆锥模型拟合**: - 使用RANSAC算法从点云中随机选择一组点,拟合圆锥模型。 - 计算拟合模型的残差,保留残差较小的点作为圆锥表面的点。 5. **滤除圆锥状物体**: - 根据拟合圆锥模型,将属于圆锥表面的点云数据标记出来。 - 将标记的点云数据从原始点云中移除。 以下是一个简单的伪代码示: ```python import pcl # 加载点云数据 cloud = pcl.load("input.pcd") # 降噪和下采样 cloud_filtered = cloud.make_statistical_outlier_filter().filter() cloud_filtered = cloud_filtered.make_voxel_grid_filter().set_leaf_size(0.01).filter() # 法线估计 ne = cloud_filtered.make_NormalEstimation() ne.set_KSearch(30) normals = ne.compute() # RANSAC拟合圆锥模型 seg = cloud_filtered.make_Segmentation() seg.set_model_type(pcl.SACMODEL_CONE) seg.set_method_type(pcl.SAC_RANSAC) seg.set_distance_threshold(0.05) seg.set_normal_distance_weight(0.1) seg.set_max_iterations(1000) seg.set_radius_limits(0.0, 2.0) seg.set_input_normals(normals) indices, model = seg.segment() # 滤除圆锥状物体 cloud_cone = cloud_filtered.extract(indices, negative=False) cloud_filtered = cloud_filtered.extract(indices, negative=True) # 保存结果 pcl.save(cloud_cone, "cone.pcd") pcl.save(cloud_filtered, "filtered.pcd") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值