这篇博文主要目的是记录关于ROS点云的一些学习过程,以及相关资料汇总。
第一部分:B站视频入门学习(https://www.bilibili.com/video/BV1JV411C7f3)
一.关于点云的基本知识:
1. PCL功能:
2. PCL库的网址:
3. 什么是点云数据?
4. PCL 主要软件包(Library)功能简介
4.Registration(点云配准):将多个数据集采集的数据汇总到同一个坐标系中,例如:使用两个激光雷达所采集到的数据,统一进行匹配,并且汇总到同一个坐标系下。核心思想是:辨别不同数据集中的点,并且找到特征点在不同数据集中的位置,一起他们的转换关系,以便于将两个激光雷达采集到的数据进行汇总使用。(例如:在同一个AGV上有两个激光雷达,用两个激光雷达采集同一个坐标系下的环境数据)--好处是:点云的精度增加+范围增加
5.kd-Tree(k-dimensional tree):是一个空间划分的数据结构,存储了一系列的K维点集合;并且使用一个树形结构将K维点进行存储;可以被用于进行高效的“一定范围内的点的搜索”和“最近临近点的搜索”,其中,临近点搜索是一个PCL库的核心方法。(efficient range searches and nearest neighbour searches)
6.octree:octree(八叉树)这个库使用点云数据,创建了一个分层树状数据结构(hierarchical tree data structure);可以实现spatial partitioning(空间划分)+downsampling(降采样)+特征值提取等。同时,octree这个库也包含了很多高效的附近范围的特征值搜索;例如:邻域本素搜索(Neighbors within Voxel Search),K邻域搜索K Nearest Neighbor Search‘等。
7.segmentation(分割):分割这个库主要包含了一系列的算法,可以用于将点云的数据进行分割;也就是将完整的点云数据分成很多小的块,然后对每个块进行处理。这个library尤其适用于处理有几个不同区域组成的点云数据。
1. 可以用来将点云数据进行重新采样(resampling),尤其适用于表面噪声较大或者多次采样的情况。
2. 与此同时,可以识别并提取出所扫描物品的表面法向信息。这个方法主要包含两个主要的算法:(1) Fast trangulation超快速三角划分 (2)Slowing meshing 用于进行表面平顺以及空洞(表面缝隙)填充。图1,2
3. 同时,这个软件库也可以进行凹包络及凸包络线的绘制。图3
5. PCL 软件库运行时候所需的依赖
(需要已经安装的软件环境见链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/compiling_pcl_posix.html#id2)
6. 一些较为有用的资源(持续更新)
PCL问题讨论论坛: http://www.pcl-users.org/
PCL github thread: https://github.com/PointCloudLibrary/pcl
PCL API+ Library: https://pointclouds.org/documentation/group__registration.html
7. 头文件存储位置:若在程序编译过程中提示找不到头文件等问题,可以在PCL官网上查找到该功能包的默认头文件存放位置,以PCL-Filter为例,网址为:https://pcl.readthedocs.io/projects/tutorials/en/latest/walkthrough.html#walkthrough
Tips:一个简单的查找某一文件的存储位置指令:命令行:which+文件名即可
8. PCL 较为常用的通用指令(https://pcl.readthedocs.io/projects/tutorials/en/latest/walkthrough.html#common)
9. PCL基本数据结构(https://pcl.readthedocs.io/projects/tutorials/en/latest/basic_structures.html#id11)
在C++程序中,点云的基本数据类型为:pcl:PointCloud
基础概念:点云是否为Organized point cloud dataset?
-> Organized point cloud (经过整理的点云数据):
有良好的数据结构,点云被分为很多的row和columns,每个点所在的行和列的信息都是已知的;
不同点云之间的关系是已知的,可以节省运算资源,采用TOF技术的相机的输出点云是这个格式的。
-> Projectable point cloud (未经处理的点云数据):
未经处理的点云文件,此种类型的点云信息可以被认为是一坨(混杂在一起的数据;
每个点的信息是由x,y组成的;采集原理是小孔成像原理,可以通过小孔成像算法计算出每个点的实际位置。
小孔成像:u = f*x/z and v = f*y/z;(https://www.cnblogs.com/majiale/p/9293499.html)
9.1 :pcl:`width
cloud.width = 640; // there are 640 points per line
在point_cloud.h的头文件中,定义了cloud.width的数据类型是:
uint_32
\\这条语句用于设定:
\\ 1.在organized 的点云数据中,这条指令可以存储每一行中,包含有多少个点。
\\ 2.在未organized的点云数据中,这条指令可以存储在这个点云文件中,共包含了多少点(总点数)
9.2 :pcl:`width
*在organized 的点云中,可以设置长宽的具体数据*
cloud.width = 640; // Image-like organized structure, with 480 rows and 640 columns,
cloud.height = 480; // thus 640*480=307200 points total in the dataset
*在没有-organized 的点云中,由于在宽度方向已经存储了所有点的数量,因此在高度方向上,设置为1即可*
cloud.width = 307200;
cloud.height = 1; // unorganized point cloud dataset with 307200 points
*在point_cloud.h的头文件中,定义了cloud.height的数据类型是:uint_32
\\这条语句用于设定:
\\ 1.在organized 的点云数据中,这条指令可以存储点云文件中共有多少行(高度方向上)。
\\ 2.在未organized的点云数据中,这个指令设置为1 即可。
\\ 3.从上边的语句可以看到,不论采用什么样的方式,不论什么样的点云数据,总点数总是一样的(殊途同归)
9.3 :pcl:`width
pcl::PointCloud cloud;
std::vector data = cloud.points;
*在point_cloud.h的头文件中,定义了point的数据类型是vector(一个容器)
\\这条语句的含义:
\\ 当创建一个格式为pcl::PointCloud的对象时,其中包含了很多点云里面的点(XYZ格式的),所以当我们要采集cloud内部的一个点的信息时,我们可以直接创建一个vector的对象,然后从cloud的对象中存取相关点的信息。(待update)
9.4 :pcl:`is_dense
:pcl:`is_dense` (bool)
例子:
if (!cloud.isOrganized ())
*在point_cloud.h的头文件中,定义了is_dense的数据类型是bool
\\这条语句的含义:
\\ 判断一个点云是否是包含有有限个点?true
\\ 或者是否存在某个点的坐标包含 Inf/NaN 无线的值;false
9.5:pcl:`sensor_origin_
:pcl:`sensor_orientation_
包含相机位姿等数据,一般情况下不用
9.6: 注意! PointT类型:
这个类型主要用于占位,PointT内已经包含了pointxyz,pointxyzi等类型,可以用后两个直接代替API中,PointT所在的位置。主要用来指带多种不同点云数据,减少复杂程度
10. 生成PCL 1.7 and PCL1.11官方文档在本地:https://www.bilibili.com/video/BV1ai4y1M7K3
11. 关联非默认安装位置的PCL库:若PCL库安装在非预设位置时,在编译使用PCL库的项目时,可能会出现找不到库的情况;具体方法详见链接中,Weird installations条目:(https://pcl.readthedocs.io/projects/tutorials/en/latest/generate_local_doc.html#generate-local-doc)