0 引言

最近项目中用到了基于PCL开发的基于平面的点云和CAD模型的配准算法,点云平面提取采用的算法如下。

1 基于PCL的点云平面分割拟合算法

2 参数及其意义介绍

(1)点云下采样

  1. 参数:leafsize

  2. 意义:Voxel Grid的leafsize参数,物理意义是下采样网格的大小,直接影响处理后点云密集程度,并对后期各种算法的处理速度产生直接影响。

  3. 值越大,点云密度越低,处理速度越快;值越小,点云密度越高,处理速度越慢。通常保持这个值,使得其他的与点数有关的参数可以比较稳定而不作大的改动。

  4. 对应的代码:

PointCloudPtr cloud(new pointCloud);
ParameterReader pd(ParameterFilePath);
double leafsize = stod(pd.getData("leafsize"));
pcl::VoxelGrid<PointT> sor;
sor.setInputCloud(CRTP::cloud_org);
sor.setLeafSize(leafsize, leafsize, leafsize);
sor.filter(*cloud);

(2)点云法线估计

  1. 参数:Ksearch

  2. 意义:估计法线时邻域内点的个数

  3. 值越小,对点云的轮廓描述越精细;值越大,对点云的轮廓描述越粗糙。

  4. 对应的代码:

ParameterReader pd(ParameterFilePath);
pcl::NormalEstimation<PointT, pcl::Normal> ne;
pcl::PointCloud<pcl::Normal>::Ptr mynormals(new pcl::PointCloud<pcl::Normal>);
pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>);
tree->setInputCloud(cloud_filter);
ne.setInputCloud(cloud_filter);
ne.setSearchMethod(tree);
ne.setKSearch(stoi(pd.getData("Ksearch")));
ne.compute(*mynormals);

(3)RegionGrowing生长聚类算法对可能是平面的点云进行分割

 算法步骤:  

  1. 算法首先计算所有点的曲率值,并将曲率最小的点作为种子(seeds),开始进行生长

  2. 以法线夹角阈值(Angle threshold)作为判断标准,对邻域内的点进行遍历判断 ,符合条件则加入当前点集,不符合则reject,并加入reject点集

  3. 以曲率阈值(Curvature threshold)作为判断标准,将邻域内符合条件的点加入到种子队列中

  4. 移除当前种子

  5. 如果当前种子队列空了,表明当前子区域分割停止,遍历其他种子区域,直到停止整个点云均被遍历完为止生长

 参数分析:

  1. 参数:MinClusterSize(最小聚类点云数目),MaxClusterSize(最大聚类点云数据)

  NumberOfNeighbours(寻找种子seed点最近的点判断是否为同类),SmoothnessThreshold(聚类的法线夹角阈值)

CurvatureThreshold(聚类的曲率阈值,可以直观地将圆柱面等区别开)

  2. 对应的代码

ParameterReader pd(ParameterFilePath);
pcl::RegionGrowing<PointT, pcl::Normal> reg;
pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>);
reg.setMinClusterSize(stoi(pd.getData("MinClusterSize")));
reg.setMaxClusterSize(stoi(pd.getData("MaxClusterSize")));
reg.setSearchMethod(tree);
reg.setNumberOfNeighbours(stoi(pd.getData("NumberOfNeighbours")));
reg.setInputCloud(CloudFilter);
reg.setInputNormals(Normals);
reg.setSmoothnessThreshold(stod(pd.getData("SmoothnessThreshold")) / 180.0 * M_PI);
reg.setCurvatureThreshold(stod(pd.getData("CurvatureThreshold")));
std::vector <pcl::PointIndices> clusters;
reg.extract(clusters);
/* wk 添加: 可视化调试 */
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_segmented(new pcl::PointCloud<pcl::PointXYZRGB>());
cloud_segmented = reg.getColoredCloud();
pcl::visualization::CloudViewer viewer("Cluster viewer");
viewer.showCloud(cloud_segmented);
while (!viewer.wasStopped())
{
}
/* wk 添加: 可视化调试 */

(4)SACSegmentation 利用RANSAC算法对平面点云进行分割并拟合

  1. 参数:MaxIterations(最大迭代次数),threshold(距离阈值,判断点是否为当前拟合平面的内点,理论上该值越大平面越粗糙)

  2. 代码

/*RanSAC拟合平面,并将平面内点分割出来*/

pcl::SACSegmentation<PointT> seg;
pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
seg.setOptimizeCoefficients(true);
seg.setModelType(pcl::SACMODEL_PLANE);
seg.setMethodType(pcl::SAC_RANSAC);
seg.setMaxIterations(stoi(pd.getData("Maxci")));
seg.setDistanceThreshold(stod(pd.getData("threshold")));
seg.setInputCloud(cloud);
seg.segment(*inliers, *coefficients); // 分割内点,另存
pcl::ExtractIndices<PointT> extract;
PointCloudPtr cloud_plane(new pointCloud);
extract.setInputCloud(cloud);
extract.setIndices(inliers);
extract.setNegative(false);
extract.filter(*cloud_plane);

3 部分效果图展示

(1)原图

(2)RegionGrowing分割效果图

4 算法的局限性

  区域生长算法分割平面步骤及问题分析:针对分辨率低、扫描质量比较差的点云,如图所示,算法无法将破碎、扭曲的大块区域识别为平面区域,只能将这部分点判断为非平面点集舍弃掉。

        

  区域生长算法通常在分割细节处比较平滑的平面点云时,具有相当的优势。但是在处理“波纹”状点云时,就没什么优势了。而实际扫描点云的细节部位很多时候是如上图所示的,为了将曲率较小的曲面区别开,而调低平滑及曲率阈值时,这类从大视角上看明显是平面的点云会被rejected,从而导致分割失效。如下图所示,RegionGrowing更适合处理接近理想点云的这类点云,而不适合处理波动起伏状的、扫描精度较差的点云。

         

29 基于PCL的点云平面分割拟合算法技术路线(针对有噪声的点云数据)的更多相关文章

  1. [OpenCV]基于特征匹配的实时平面目标检测算法

    一直想基于传统图像匹配方式做一个融合Demo,也算是对上个阶段学习的一个总结. 由此,便采购了一个摄像头,在此基础上做了实时检测平面目标的特征匹配算法. 代码如下: # coding: utf-8 ' ...

  2. 2d-Lidar 点云多直线拟合算法

    具体步骤: EM+GMM(高斯模糊模型) 点云分割聚类算法的实现. 基于RANSAC单帧lidar数据直线拟合算法实现. 多帧lidar数据实时直线优化算法实现. 算法实现逻辑: Struct lin ...

  3. [转帖]腾讯云TStack获下一代云计算技术创新奖 与鲲鹏等产品实现兼容性测试

    http://www.techweb.com.cn/cloud/2019-12-16/2769286.shtml [TechWeb]12 月 16 日消息,在中国电子技术标准化研究院主办的“第九届中国 ...

  4. 沙龙报名 | 京东云DevOps——自动化运维技术实践

    随着互联网技术的发展,越来越多企业开始认识DevOps重要性,在企业内部推进实施DevOps,期望获得更好的软件质量,缩短软件开发生命周期,提高服务稳定性.但在DevOps 的实施与落地的过程中,或多 ...

  5. 深度学*点云语义分割:CVPR2019论文阅读

    深度学*点云语义分割:CVPR2019论文阅读 Point Cloud Oversegmentation with Graph-Structured Deep Metric Learning 摘要 本 ...

  6. CVPR2020:4D点云语义分割网络(SpSequenceNet)

    CVPR2020:4D点云语义分割网络(SpSequenceNet) SpSequenceNet: Semantic Segmentation Network on 4D Point Clouds 论 ...

  7. Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图

    Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图 分类: OpenCV图像处理2013-02-21 21:35 6459人阅读 评论(8) 收藏 举报   原文链接  ht ...

  8. PCL点云库:ICP算法

    ICP(Iterative Closest Point迭代最近点)算法是一种点集对点集配准方法.在VTK.PCL.MRPT.MeshLab等C++库或软件中都有实现,可以参见维基百科中的ICP Alg ...

  9. 基于TFS的.net技术路线的云平台DevOps实践

    DevOps是近几年非常流行的系统研发管理模式,很多公司都或多或少在践行DevOps.那么,今天就说说特来电云平台在DevOps方面的实践吧. 说DevOps,不得不说DevOps的具体含义.那么,D ...

随机推荐

  1. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_01 Collection集合_5_迭代器的代码实现

    迭代器的类型和collection一样.都是String类型的 判断集合内是不是有元素 取出第一个元素 多次next获取所有的值 没有元素,再去取就会抛出异常. 适应while for循环的格式了解一 ...

  2. Jmeter之CSV Data Set Config

    在很多情况下,需要针对测试数据做参数化操作,Jmeter提供了很好用的CSV Data Set Config插件. 一.界面显示 二.界面说明 1.名称:标识,建议设置为该组件是提供什么功能 2.注释 ...

  3. 06 使用bbed提交delete的数据--01

    使用bbed模拟delete提交操作 --session 1 TEST@ orcl )); Table created. TEST@ orcl ,'AAAAA'); row created. TEST ...

  4. 练习3-python-创造百万条数据库数据

    有时候需求大批量的数据做测试支撑,如果使用传统的添加数据的方式可能比较耗费时间,利用python可以轻松的完成这项任务,还可以后续维护使用脚本. 方法1:insert into table selec ...

  5. UVa 11582 Colossal Fibonacci Numbers! 紫书

    思路是按紫书上说的来. 参考了:https://blog.csdn.net/qwsin/article/details/51834161  的代码: #include <cstdio> # ...

  6. c语言秋季作业2

    问题 答案 这个作业属于哪个课程 C语言程序设计I 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-4/homework/8657 我在这 ...

  7. Windows + Ubuntu 16.04 双系统安装详细教程(转)

    转载自:http://www.cnblogs.com/Duane/p/6776302.html 前言:本篇文章是对之前文章的更新,更新的主内容是把原来用手机拍摄的图片换成了虚拟机的截图,以及对磁盘划分 ...

  8. Oracle数据库控制台常用命令

    安装好数据库以后可以通过“Win+R”打开控制台,在控制台登录Oracle输入命令来操作数据库. SQLPlus命令: SQLPlus命令是用来登录Oracle数据库的命令,有两种写法,分别如下: ( ...

  9. #10017 传送带(SCOI 2010)(三分套三分)

    [题目描述] 在一个 2 维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段 AB 和线段 CD.lxhgww 在 AB上的移动速度为 P ,在 CD 上的移动速度为 Q,在平 ...

  10. Python内建函数reduce()用法

    reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,下面讲述Python内建函数reduce()用法. ...