首页 > 其他分享 >PCL 点云拟合 Ransac拟合圆柱

PCL 点云拟合 Ransac拟合圆柱

时间:2024-11-16 15:50:54浏览次数:3  
标签:Ransac 圆柱 pcl 拟合 点云 new include cloud

目录

内容抄自CSDN点云侠:【2024最新版】PCL点云处理算法汇总(C++长期更新版)。质量无忧,永久免费,可放心复制粘贴。

一、概述

  圆柱的Eigen::VectorXf参数为7个。分别是:

圆柱轴上一点的x坐标;
圆柱轴上一点的y坐标;
圆柱轴上一点的z坐标;
圆柱轴方向的x;
圆柱轴方向的y;
圆柱轴方向的z;
圆柱半径r。

1.1 原理

  RANSAC(Random Sample Consensus)算法是一种常用的计算机视觉中的迭代优化技术,用于从一组数据点中找到最佳模型,比如圆柱体,在存在噪声和异常值的情况下。它通过随机选择小样本集合(通常称为"候选子集"),尝试对这些点进行某种假设(如圆柱体的参数估计),然后计算这个假设是否能很好地解释大部分原始数据。如果大多数点都能满足该假设,则认为找到了一个好的模型。
  对于拟合圆柱,RANSAC会先随机选取一些点作为初始圆柱中心、长度和直径的猜测,接着计算这些点到圆柱表面的距离,如果距离误差在一个阈值内,就认为这组点支持当前的圆柱模型。不断重复这个过程,直到达到预设的迭代次数或找到足够多的数据点支持的“一致”集合。最后,RANSAC会选择那个解释了最大比例点的圆柱参数作为最终结果。

1.2 实现步骤

  RANSAC(Random Sample Consensus)算法是一种用于估计模型参数的迭代概率方法,在计算机视觉领域广泛应用,包括圆柱体的拟合。以下是RANSAC圆柱拟合的基本步骤:

  1. 随机抽样:从输入数据集中随机选取一组点作为初始候选样本。
  2. 模型构建:基于选定的点集,尝试构造一个圆柱模型,例如通过最小二乘法计算出圆心、半径以及轴向信息。
  3. 一致性检查:检查这组点是否都近似满足圆柱模型,通常通过计算每个点到模型的残差(距离),如果大部分点的残差在预设的阈值内,则认为这个模型是一致的。
  4. 计数和投票:重复上述过程多次,每次选择新的随机点集,记录下一致性的次数。当某个模型达到预设的最少一致性支持次数时,就认为找到了一个好的模型。
  5. 最佳模型选择:所有经过检验的一致性模型中,选择具有最高支持度的那个作为最终圆柱模型。
  6. 评估和输出:对所有数据点应用选定的模型,得到拟合结果,并计算残差,评估模型的精度。

1.3应用场景

  RANSAC(随机采样一致性)算法是一种用于在含有噪声数据的情况下估计模型参数的迭代方法,特别适用于平面、直线、圆、圆柱等基本几何结构的拟合。在实际应用中,RANSAC常用于计算机视觉领域,例如:

  1. 三维扫描:对激光雷达点云数据进行处理时,可能会包含一些错误测量点,RANSAC可以帮助筛选出最有可能代表真实圆柱的样本,并估计其尺寸和方向。
  2. 工业检测:在产品质量控制中,通过图像分析识别产品是否符合预期的圆柱形状,比如管材、零件的表面缺陷检测。
  3. 机器人定位:机器人手臂抓取物体时,需要找到目标物体的中心和旋转轴,RANSAC可以用来检测并拟合一组特征点,确定圆柱坐标。
  4. 医学成像:在CT或MRI数据中,识别和分割血管或神经纤维束的圆柱结构也是常见应用。

二、关键函数

2.1 头文件

#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_cylinder.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

2.2 加载点云数据

// ------------------------------加载点云数据------------------------------
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	if (pcl::io::loadPCDFile<pcl::PointXYZ>("Cylinder.pcd", *cloud) < 0)
	{
		PCL_ERROR("Couldn't read file \n");
		return -1;
	}

2.3 计算法线

// -------------------------------计算法线--------------------------------
	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(10);		// K近邻搜索个数
	n.compute(*normals);

2.4 拟合圆柱

// -------------------------------拟合圆柱--------------------------------
	pcl::SampleConsensusModelCylinder<pcl::PointXYZ, pcl::Normal >::Ptr model(new pcl::SampleConsensusModelCylinder<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::PointCloud<pcl::PointXYZ>::Ptr cloudInliers(new pcl::PointCloud<pcl::PointXYZ>);
	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;

2.5 可视化

// -----------------------------结果展示--------------------------------
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("ModelCylinder"));
	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));
	}


三、完整代码

#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_cylinder.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>);
	if (pcl::io::loadPCDFile<pcl::PointXYZ>("Cylinder.pcd", *cloud) < 0)
	{
		PCL_ERROR("Couldn't read file \n");
		return -1;
	}

	// -------------------------------计算法线--------------------------------
	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(10);		// K近邻搜索个数
	n.compute(*normals);
	
	// -------------------------------拟合圆柱--------------------------------
	pcl::SampleConsensusModelCylinder<pcl::PointXYZ, pcl::Normal >::Ptr model(new pcl::SampleConsensusModelCylinder<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::PointCloud<pcl::PointXYZ>::Ptr cloudInliers(new pcl::PointCloud<pcl::PointXYZ>);
	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("ModelCylinder"));
	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);
}

四、结果展示

在这里插入图片描述

标签:Ransac,圆柱,pcl,拟合,点云,new,include,cloud
From: https://blog.csdn.net/m0_51204289/article/details/143093604

相关文章

  • 人工智能同样也会读死书----“过拟合”
    上一篇:《“嵌入”在大语言模型中是解决把句子转换成向量表示的技术》序言:我们常常会说某某人只会“读死书”,题目稍微变一点就不会做了。这其实是我们人类学习中很常见的现象。可是你知道吗?人工智能其实更容易“读死书”。不过在人工智能领域,我们有个听起来高大上的说法,叫“过拟......
  • 基于特征点模型的人脸和面具拟合的方法研究
    目录第一章:引言1.1研究背景1.2研究意义1.3研究目标1.4文章结构第二章:特征点模型与人脸检测2.1人脸检测的选择2.2特征点检测的实现2.3特征点的重要性第三章:面具拟合方法3.1正脸情况的仿射变换3.2正脸仿射变换的代码实现3.3仿射变换的效果分析第四章:侧脸......
  • 点云学习笔记17——PCL保存提取到的二维点云边界(即凸包边界)
    #include<pcl/io/pcd_io.h>#include<pcl/io/ply_io.h>#include<pcl/point_types.h>#include<pcl/features/normal_3d.h>#include<pcl/filters/project_inliers.h>#include<pcl/segmentation/sac_segmentation.h>#include<......
  • 点云学习笔记16——提取点云的边界,填充边界
    #include<iostream>#include<algorithm>#include<pcl/io/pcd_io.h>#include<pcl/point_types.h>#include<pcl/visualization/pcl_visualizer.h>voidBoundaryExtraction(pcl::PointCloud<pcl::PointXYZ>::Ptrcloud,pcl::Poi......
  • 21天教你学会PCIe专栏(5)--事务层(Transaction Layer)
    目录第5天:事务层(TransactionLayer)课程目标课程内容1.事务层概述2.事务类型3.请求和响应机制4.事务层的配置和管理5.实际应用示例课后练习结语第5天:事务层(TransactionLayer)课程目标理解PCIe事务层的基本概念和功能掌握事务类型及其工作原理了解请求和响应......
  • PCL 点云分割 分割多个平面
    目录一、概述1.1原理1.2实现步骤1.3应用场景二、代码实现2.1关键函数2.1.1RANSAC平面分割2.1.2剔除已分割的平面2.1.3可视化点云2.2完整代码三、实现效果PCL点云算法汇总及实战案例汇总的目录地址链接:PCL点云算法与项目实战案例汇总(长期更新)一、概述  ......
  • PCL 点云分割 Ransac分割3D球体
    目录一、概述1.1原理1.2实现步骤1.3应用场景二、代码实现2.1关键函数2.1.1球体拟合2.1.2可视化2.2完整代码三、实现效果PCL点云算法汇总及实战案例汇总的目录地址链接:PCL点云算法与项目实战案例汇总(长期更新)一、概述        在点云数据处理中,RANSAC(随......
  • 理解@Transactional
    在SpringBoot中,@Transactional注解仍然是Spring框架提供的一个核心注解,用于声明式事务管理。SpringBoot通过自动配置和简化配置,使得在SpringBoot应用程序中使用@Transactional注解变得更加方便。本文将深入探讨@Transactional注解在SpringBoot中的使用方法、......
  • Spring学习笔记_30——事务接口PlatformTransactionManager
    PlatformTransactionManager是Spring框架中事务管理的核心接口,它负责管理事务的创建、提交和回滚等操作。源码/**Copyright2002-2020theoriginalauthororauthors.**LicensedundertheApacheLicense,Version2.0(the"License");*youmaynotusethis......
  • 点云学习笔记14——PCL点云文件投影到平面
    #include<iostream>#include<pcl/io/pcd_io.h>#include<pcl/point_types.h>#include<pcl/ModelCoefficients.h>#include<pcl/filters/project_inliers.h>#include<pcl/visualization/pcl_visualizer.h>#include<boost/th......