PCL库的安装与基本使用
Ubuntu 20.04 安装 PCL 库
推荐安装方法:
1 | sudo apt install libpcl* |
如果不用最新的PCL功能的话,正常点云处理显示等使用还是没问题的。
源码安装(建议使用cmake-gui):
下载PCL-1.10,一定要下载1.10,因为ROS安装的过程中会安装pcl-1.10的库,正常使用没问题,但是缺少一些新功能例如pcl/surface/on_nurbs
,我想要使用这个库,因此能够从源码编译,如果使用其它版本安装,会出现冲突例如error: redefinition of
1 | cd pcl-pcl-1.10 |
选择source code为下载解压的文件夹pcl-pcl-1.10,第二个选择刚创建的build文件夹
点击Configure
,点击Finish
,出现一些初始化配置。
注意要选BUILD_surface_on_nurbs
,不然会报错pcl/surface/on_nurbs/fitting_surface_tdm.h: 没有那个文件或目录
,当然最好把能选的都选了,我这里除了默认的,还额外勾选了
- BUILD_CUDA
- BUILD_GPU
- BUILD_examples
- BUILD_simulation
- BUILD_surface_on_nurbs
- BUILD_kinfu_tools
直到没有红色区域之后,点击configure
,配置完成后点击generate
按钮,会在build文件夹下生成工程文件,然后关闭cmake-gui界面就可以了
1 | make |
源码卸载
1 | sudo updatedb |
PCL基本使用
1. 基本数据类型
- 点:
pcl::PointXYZ
、pcl::PointXYZRGB
、pcl::PointXYZI
- 点云:
pcl::PointCloud
- 宽高:
PointCloud::width
与PointCloud::height
,都为int
类型,如果是规律排列的,则分别代表点云的长宽,如果是无序的则高为1,宽为点数量 - 点:
PointCloud::points
存放点的vector变量 - 指针:
PointCloud::Ptr
:只想PointCloud
的智能指针
- 宽高:
2. 读写点云数据
读取点云
1 | pcl::PCDReader pcd_reader; |
保存点云
1 | pcd_writer.write<pcl::PointXYZ>("xxx.pcd", *cloud, false); //false表示保存为ASCII文件 |
3. 点云滤波
直通滤波:直接对x,y,z三个方向上设置要保留的点的距离范围,滤除距离范围外的点
1 | pcl::passThrough<pcl::PointXYZ> pass; |
体素滤波:将空间划分为一定体积的网格,用每个网格内所有的点的质心来代替所有的点,将每个网格内的点云压缩为一个质心点。
1 | pcl::VoxelGrid<pcl::PointXYZ> vg; |
离群点滤波:统计每个点与周围最临近的若干个点的平均距离,若平均距离大于设定的阈值则判定为离群点而滤除。
1 | pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; |
半径滤波:对一定半径范围内点数少于设定值的点进行滤波。
1 | pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem; |
4. 点云聚类与分割
RANSAC:随机抽样一致性算法,解决了传统最小二乘法全数据参与不能排除错误数据干扰的问题,可以拟合出更精确的模型,算法思路如下:
- 在原本数据集中随机抽取最少可以拟合出模型的数据量进行拟合。最少数据量一般由模型位置的参数来确定(例如直线就是两个),假设拟合得到的模型为M。
- 利用M,对数据集中剩余数据计算各个数据与模型M的误差值p,若p<给定阈值n,则认为该数据为内点;若大于阈值,则认为是外点。计算所有内点和外点,得到内点的集合S。
- 判断集合S的点数是否大于给定的点数阈值K,若大于K,则认为该次拟合的模型适合离得。若小于K,则认为不合理,直接丢弃。
- 若模型合理,则在用得到的内点集合S与之前随机得到的点再拟合依次模型,得到新的模型M’
- 重新随机采样,重复1-4过程,得到多个模型M’。
- 若采样次数达到给定阈值,则停止采样,就在得到的M’模型中,选择最优的作为最终结果。或者当某一模型M’的误差在给定精度阈值内,则停止采样,以该模型为最终结果。
平面分割
1 | pcl::PointIndices::Ptr inliers_plane; |
法线估计
1 | pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>); //保存法线信息的点云 |
圆柱分割
1 | pcl::PointIndices::Ptr inliers_cylinder; |
索引提取
1 | pcl::PointIndices::Ptr inliers; |
5. 可视化
程序中可视化
第一种方式,会造成程序暂停,需要先在点云窗口中按w
,调整到一个比较好的视角,退出时按q
。
1 | pcl::visualization::CloudViewer viewer("Simple Cloud Viewer"); //括号内是窗口名称 |
第二种方式,将显示放在了循环内,不会造成程序中断
1 | pcl::visualization::CloudViewer viewer("Simple Cloud Viewer"); |
命令行可视化
1 | pcl_viewer xxx.pcd |
参考链接: