说好了要学习点云处理,那就从基础做起,我将根据《ROS机器人程序设计》中点云部分的内容写一系列学习笔记。
完成后,再学习点云库PCL进阶。
点云是由飞行时间(Time of Flight)摄像头和激光扫描仪在3D空间采集的有限点集构成的。
点云库(PCL)提供了大量数据类型和数据结构,不仅能方便的表示采样空间中的点,而且可以表示采样空间的不同属性,比如颜色、法向量等。PCL同样提供了许多最先进的算法对数据样本进行处理,比如滤波、模型估计、表面重建等。
点云库为处理3D数据提供了一组数据结构和算法,ROS的PCL接口提供了一组消息以及消息与PCL数据结构之间的转换函数。
点云中最重要的公共字段:
- header:pcl::PCLHeader类型,指定了点云的获取时间
- points:std::vector<PointT,…>类型,它是存储所有点的容器
- width:指定了点云组成一种图像时的宽度,否则它包含的是云中点的数量
- height:指定了点云组成一种图像时的高度,否则它总是1
- is_dense:指定了点云中是否有无效值(无穷大或NaN值)
- sensor_origin:Eigen::Vector4f类型,并且定义了传感器根据相对于原点的平移所得到的位姿
- sensor_orientation:Eigen::Quaternionf类型,并且定义了传感器旋转所得到的位姿
PCL算法利用这些字段来处理数据,并且用户可以利用它们来创建自己的算法。
PCL定义了许多不同类型的点,最常用到的类型如下:
- pcl::PointXYZ:最简单也可能最常用到的点类型,只存储了3D xyz信息
- pcl::PointXYZI:在pcl::PointXYZ的基础上,还包含了一个描述点亮度(intensity)的字段
- pcl::PointXYZRGBA:存储3D信息,也存储颜色(RGB)和透明度(A=Alpha)
- pcl::PointXYZRGB:存储3D信息,也存储颜色(RGB)
- pcl::Normal:最常用的点类型,表示曲面上给定点处的法线以及测量测量的曲率
- pcl::PointNormal:包含了给定点所在曲面法线以及曲率信息,还包含3D信息
PCL算法都是模板化的,不仅可以使用已经可用的类型,还可以使用用户定义的语法正确的类型。
PCL的开发者把每个算法做出一个类,这个类属于一个有着特定共性的继承类。这就允许开发者通过获取已经存在的算法并加上新算法所需的参数,以重用这些算法,并且允许用户通过存取器轻松地为算法提供他所需要的参数值,而其余的参数都去默认值。
下面代码展示了通常是如何使用PCL算法的:
通过ROS自带的基于消息的通信系统,ROS的PCL接口提供了与PCL数据结构进行通信所需要的方法。
最重要的消息类型如下:
- std_msgs::Header:不是真的消息类型,通常是每个ROS消息的一部分,包含消息发送时间、序列号和坐标系名称等信息,等价的PCL类型是pcl::Header
- sensor_msgs::PointCloud2:最重要的消息类型,用来转换pcl::PointCloud类型
- pcl_msgs::PointIndices:存储了点云中点的索引,等价的PCL类型是pcl::PointIndices
- pcl_msgs::PolygonMesh:保存了描绘网格、顶点和多边形的信息,等价的PCL类型是pcl::PolygonMesh
- pcl_msgs::Vertices:将一组顶点的索引保存在一个数组中,等价的PCL类型是pcl::Vertices
- pcl_msgs::ModelCoefficients:存储了一个模板的不同系数,等价的PCL类型是pcl::ModelCoefficients
通过ROS的PCL功能包提供的转换函数可以将前面的消息转换为PCL类型或者从PCL类型转换为消息。
指定了一组函数执行消息与PCL类型的转换:
void toROSMsg(const pcl::PointCloud<T> &, sensor_msgs::PointCloud2 &);
void fromROSMsg(const sensor_msgs::PointCloud2 &, pcl::PointCloud<T> &);
void moveFromROSMsg(const sensor_msgs::PointCloud2 &, pcl::PointCloud<T> &);