【PCL】Segmentation 模块—— 圆柱模型分割(Cylinder model segmentation)

1、简介

PCL(Point Cloud Library)中的圆柱模型分割Cylinder Model Segmentation是一种从点云数据中提取圆柱体模型的技术。它通过识别点云中符合圆柱体几何形状的部分,将圆柱体从其他几何形状中分离出来。

1.1 主要步骤

  1. 预处理

    • 对点云进行去噪、下采样等操作,以减少数据量并提升处理效率。
  2. 法线估计

    • 计算点云中每个点的法线,用于后续的模型拟合。
  3. 模型拟合

    • 使用RANSAC(随机采样一致性)算法拟合圆柱体模型。RANSAC通过随机采样点来估计模型参数,并评估其与点云的拟合程度。
  4. 分割

    • 根据拟合的圆柱体模型,将点云中符合该模型的内点(inliers)与不符合的外点(outliers)分离。
  5. 后处理

    • 对分割结果进行优化,如去除噪声或进一步细化圆柱体参数。

1.2 应用场景

  • 工业检测:识别管道、圆柱形零件等。
  • 机器人:用于导航和物体抓取。
  • 建筑建模:提取建筑物中的圆柱形结构。

2、代码实现

代码为圆柱形模型运行一个样本共识分割,由于数据中存在噪声,圆柱模型并不完美。为了使示例更实际一些,将以下操作应用于输入数据集(按顺序):

  • 距离大于1.5米的数据点被过滤

  • 估计每个点的表面法线

  • 一个平面模型(描述我们演示数据集中的表)被分割并保存到磁盘上

  • 一个圆柱形模型(在我们的演示数据集中描述杯子)被分割并保存到磁盘上

2.1 cylinder_segmentation.cpp

#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/passthrough.h>
#include <pcl/features/normal_3d.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>

typedef pcl::PointXYZ PointT;

int
main ()
{
   
  // All the objects needed
  pcl::PCDReader reader;
  pcl::PassThrough<PointT> pass;
  pcl::NormalEstimation<PointT, pcl::Normal> ne;
  pcl::SACSegmentationFromNormals<PointT, pcl::Normal> seg; 
  pcl::PCDWriter writer;
  pcl::ExtractIndices<PointT> extract;
  pcl::ExtractIndices<pcl::Normal> extract_normals;
  pcl::search::KdTree<PointT>::Ptr tree (new pcl::search::KdTree<PointT> ());

  // Datasets
  pcl::PointCloud<PointT>::Ptr cloud (new pcl::PointCloud<PointT>);
  pcl::PointCloud<PointT>::Ptr cloud_filtered (new pcl::PointCloud<PointT>);
  pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
  pcl::PointCloud<PointT>::Ptr cloud_filtered2 (new pcl::PointCloud<PointT>);
  pcl::PointCloud<pcl::Normal>::Ptr 
### PCL 1.8.1 中的圆柱分割算法实现与使用 在 Point Cloud Library (PCL) 版本 1.8.1 中,圆柱分割通常通过 `SACSegmentation` 类来完成。该类实现了基于随机采样一致性(Sample Consensus, SAC)模型拟合方法。 #### 圆柱分割的具体实现 为了执行圆柱分割,可以采用如下代码: ```cpp #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/filters/extract_indices.h> #include <pcl/features/normal_3d.h> #include <pcl/sample_consensus/method_types.h> #include <pcl/sample_consensus/model_types.h> #include <pcl/segmentation/sac_segmentation.h> int main(int argc, char** argv) { // 加载点云数据 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); if (pcl::io::loadPCDFile<pcl::PointXYZ>("your_point_cloud.pcd", *cloud) == -1) { std::cerr << "Couldn't read file \n"; return (-1); } // 创建法线估计对象并计算法线 pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne; pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>()); ne.setInputCloud(cloud); ne.setSearchMethod(tree); pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); ne.setRadiusSearch(0.03); // 设置半径范围内的邻域搜索参数 ne.compute(*normals); // 将原始点云和对应的法线组合成一个新的点云结构 pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>); pcl::concatenateFields(*cloud, *normals, *cloud_with_normals); // 定义 SAC 分割pcl::SACSegmentationFromNormals<pcl::PointNormal, pcl::Normal> seg; pcl::ModelCoefficients::Ptr coefficients_cylinder(new pcl::ModelCoefficients()); pcl::PointIndices::Ptr inliers_cylinder(new pcl::PointIndices()); // 可选设置:最大迭代次数以及距离阈值 seg.setMaxIterations(10000); seg.setDistanceThreshold(.01); // 必要设置:指定模型类型为圆柱体,并提供输入数据集及其关联的表面法向量 seg.setModelType(pcl::SACMODEL_CYLINDER); seg.setMethodType(pcl::SAC_RANSAC); seg.setOptimizeCoefficients(true); seg.setInputCloud(cloud_with_normals); seg.setInputNormals(normals); // 设定最小曲率条件以过滤掉不符合要求的结果 seg.setMinPoints(1000); float eps_angle = static_cast<float>(M_PI / 4); // ±45度角作为允许的最大偏差角度 seg.setEpsAngle(eps_angle); // 执行分割过程 seg.segment(*inliers_cylinder, *coefficients_cylinder); if(inliers_cylinder->indices.size() == 0){ std::cout<<"No points detected as part of a cylinder."<<std::endl; return(-1); } } ``` 此段程序展示了如何加载一个 `.pcd` 文件格式的三维点云文件,接着创建了一个法线估算实例用于获取每个点处的方向信息[^2]。之后利用这些方向信息辅助进行更精确的几何特征匹配——即寻找最佳拟合给定点集合的圆柱模型。最后一步则是调用 `seg.segment()` 函数来进行实际的数据处理工作,在这里会返回两个主要结果变量:一个是表示哪些索引位置上的点属于所发现的最佳拟合圆柱的一部分(`*inliers_cylinder`);另一个则包含了描述这个理想化圆柱形状所需的全部系数(`*coefficients_cylinder`)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值