PCL求解规则点云的拟合圆

该文章引用自https://blog.csdn.net/Asher_zheng/article/details/100019353,https://blog.csdn.net/baidu_40840693/article/details/103928636
仅作为学习记录

前言

PCL中可通过RANSAC算法来计算一些规则点云的数学模型,并返回模型的参数。
RANSAC算法可用来从点云中提取圆形点云并得到圆形点云的圆心、半径及圆所在平面的法向量
(适合于3D Circle)。
在PCL的RANSAC算法模型中,有2D Circle和3D Circle两种圆形模型,以下分作简要介绍。

2D Circle模型

2D Circle模型是从原点云中提取表达式为 (x-a)²+(y-b)²=r² 的点云圆,因此得到的点云是一个圆柱体的侧面,使用方式如下:
(1) 包含头文件:

#include <pcl/sample_consensus/sac_model_circle.h>

(2) 定义模型:

pcl::SampleConsensusModelCircle2D<pcl::PointXYZ>::Ptr model_circle2D
             (new pcl::SampleConsensusModelCircle2D<pcl::PointXYZ>(cloud));
///cloud为要求解拟合圆的点云        

(3) RANSAC提取2D圆形点云:

pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_circle2D);
ransac.setDistanceThreshold(.01);
ransac.computeModel();
ransac.getInliers(inliers);

(4) 得到圆心坐标及半径并输出:

Eigen::VectorXf modelParas;
ransac.getModelCoefficients(modelParas);
std::cout << modelParas<< "\n\n";

演示结果为:

第一个原始点云如最左边图所示,右边两张图为此点云应用RANSAC得出2D Circle模型的不同角度,可以看出是一个圆柱体的侧面:
在这里插入图片描述
所计算出的圆心坐标及半径如下:
在这里插入图片描述

3D Circle模型

3D Circle模型得到的是三维空间的圆形点云,其数学模型可由圆心,半径及圆所在平面的法向量表示,具体计算方式如下:

(1) 包含头文件:

#include <pcl/sample_consensus/sac_model_circle.h>

(2) 定义模型:

pcl::SampleConsensusModelCircle3D<pcl::PointXYZ>::Ptr
		model_circle3D(new pcl::SampleConsensusModelCircle3D<pcl::PointXYZ>(cloud));

(3) RANSAC提取3D圆形点云:

pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_circle3D);
ransac.setDistanceThreshold(.01);
ransac.computeModel();
ransac.getInliers(inliers);

(4) 得到模型参数并打印出模型参数:

Eigen::VectorXf modelParas;
ransac.getModelCoefficients(modelParas);
std::cout << modelParas<< "\n\n";

演示结果为:

在这里插入图片描述
所计算出的圆心坐标及半径如下,前三个数值为圆心坐标(x, y, z),第四个数值为计算出的圆形点云的半径,最后三个为圆形点云所在平面的法向量:

在这里插入图片描述

具体实例

    ///定义了final点云,存放最后的结果
    pcl::PointCloud<pcl::PointXYZ>::Ptr final (new pcl::PointCloud<pcl::PointXYZ>);
    ///存放拟合圆
    std::vector<int> inliersCircle3D;
    
    ///oriCloud_inliers:待求解拟合圆的原始点云
    pcl::SampleConsensusModelCircle3D<PointT>::Ptr socCircle3D(new pcl::SampleConsensusModelCircle3D<PointT> (oriCloud_inliers));
    
    ///求解拟合圆
    pcl::RandomSampleConsensus<PointT>::Ptr ransac ( new pcl::RandomSampleConsensus<PointT> (socCircle3D) );
    ransac->setDistanceThreshold(0.1f);
    ransac->computeModel();
    ransac->getInliers(inliersCircle3D);
    
    ///获取拟合圆的参数
    Eigen::VectorXf circle_coeff;
    ransac->getModelCoefficients(circle_coeff);
   
    PointCloud::Ptr finalCircle3D(new PointCloud);
    pcl::copyPointCloud (*oriCloud_inliers, inliersCircle3D, *finalCircle3D);
    std::cout<<"circle_coeff "<<"rows="<<circle_coeff.rows()<<"cols="<<circle_coeff.cols()<<"coefficeints="<<circle_coeff.size()<<std::endl;
    
    ///可视化
    pcl::visualization::PointCloudColorHandlerCustom<PointT> color_handler5(finalCircle3D, 230, 50, 12);//红色
    view->addPointCloud(finalCircle3D, color_handler5, "CH5");

copyPointCloud()函数

常见的使用方法有两种:

Part 1:完全拷贝到新的点云之中:pcl::copyPointCloud (const pcl::PointCloud &cloud_in,pcl::PointCloud &cloud_out)

pcl::PointCloud<pcl::PointXYZ>::Ptr src(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointNormal>::Ptr src_PN(new pcl::PointCloud<pcl::PointNormal>);

pcl::io::loadPCDFile("src.pcd",*src);//载入原数据
pcl::io::loadPCDFile("src_pn.pcd", *src_PN);//载入原数据

pcl::copyPointCloud(*src, *src_PN);//src中的xyz覆盖掉src_PN中的xyz值

pcl::io::savePCDFile("src_with_normal.pcd", *src_PN);

Part 2:部分索引的使用:pcl::copyPointCloud (const pcl::PointCloud &cloud_in, const std::vector &indices,pcl::PointCloud &cloud_out)

pcl::PointCloud<pcl::PointXYZ>::Ptr src(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("src.pcd",*src);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudout(new pcl::PointCloud<pcl::PointXYZ>);
std::vector<int>indexs = { 0,2,6 };//索引
pcl::copyPointCloud(*src, indexs, *cloudout);
pcl::io::savePCDFile("cloud_out.pcd", *cloudout);//只取src中的第1,第3个,第7个点赋值到新的cloudout中。
  • 6
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值