为开源点云库PCL贡献代码(一)
点云(Point Cloud)
接触三维重建或者立体视觉相关问题的时候,点云是第一个需要掌握的概念。
简单来讲,点云就是多唯空间中的点的集合,一般而言,指的是三维空间中的点集。在PCL中,点云被表示成一种数据结构。我们用X-Y-Z三维来表示一个采样曲面的几何坐标。如下,当我们对其表面着色后,点云变为4唯的。
获取点云的方式有很多:比如一些硬件传感器(如立体相机,3D扫描仪,TOF相机),或者通过程序计算,比如SFM算法。
很高兴的是PCL原生支持OpenNI从而能够很好的直接处理深度相机( PrimeSensor 3D cameras, Microsoft Kinect和 Asus XTionPRO)的数据。另外说明一下,Kinect和华硕的这款本质上都是采用PrimeSense的结构光技术的深度相机。OpenNI现在也由Primesense维护,而Primesense已被苹果收购。有时间对这些硬件和产业,包括眼镜和深度相机也做一下归纳吧。
PCL(Point Cloud Library)简介
点云库Point Cloud Library (or PCL) 是一个大型的用于处理2D/3D图像和点云的开源项目。它实现了立体视觉领域众多的前沿算法,包括滤波,特征提取,表面重建,相机标定,模型拟合,分割,可视化等许多功能,如图。
PCL项目遵循 3-clause BSD license 协议,能同时用于学术和商业用途。它也是跨平台的,目前支持五大平台(Linux,MacOS, Windows, 和 Android/iOS. )
目前,与立体视觉结合最紧密的研究方向当属机器人了,PCL与机器人操作系统ROS集成良好,并已经有很好的实际应用。SLAM移动机器人导航,尤其是VisualSLAM领域的蓬勃发展,VR/AR的不断发酵,三维重建等的发展会更加促进立体视觉的发展,PCL的重要性不言而喻。
PCL代码风格良好,全部由C++编写,其中的矩阵操作使用了线性代数函数库Eigen。此外,PCL也支持并行化,如OpenMP和Intel Threading Building Blocks。在PCL的所有模块中,数据的传递都是通过Boost的智能指针Share Pointer,如此可以减少系统中数据的多余复制。
再来说下PCL的各个模块,它们可以独立编译,独立运行。它的一般工作模式如下:
- 新建一个处理类(Project)(比如,filter,feature estimation,segmentation等)
- 使用
setInputCloud
将点云(Point Cloud)数据输入到处理模块中 - 设定一些必要的参数
- 调用
compute
或者其他的函数如(filter,segment等)得到输出
主要模块包括:
-
libpcl_filter:
功能包括將采样(downsampling),例外点去除,索引提取,投影等 -
libpcl_features:
实现了许多3D特征,比如表面法向量和曲率,边缘点估计,不变矩(moment invariants),主曲率,PFH和FPFH(Fast point feature histogram)描述子,旋转图像(spin image),积分图像(integral image),NARF描述符,RIFT,RSD,VFH,基于强度数据的SIFT算法等。
后面我觉得也会有一些采用深度学习方法训练特征的算法加入到PCL中。 -
libpcl_io:
I/O操作的函数,如读写点云数据PCD(point cloud data)的函数 -
libpcl_segmentation:
实现了聚类提取,或者为某些参数模型通过采样一致的方法提供模型拟合等 -
libpcl_surface:
实现了表面重建的一些算法,如meshing,圖包算法(convex hull)和移动最小二乘(moving least squares)等 -
libpcl_registration:
ICP匹配算法等 -
libpcl_keypoints:
预处理的一些算法,对关键点预处理方便后续提取特征描述符 -
libpcl_range_image:
深度图(range image)的建立函数等
为了保证操作的正确性,上述每个库中的方法和类都提供了单元和回归测试,如果添加的新功能或者某个修改没有通过测试,该作者会收到通知。
PCL的设计哲学
Perception Processing Graphs
这个道理的潜在认为对点云处理的各个模块可以认为是独立编译的一部分,通过调整参数可以分别应对某一类问题。
由于点云数据通常比较大,为了避免不必要的拷贝和关键程序的序列化,PCL创建了nodelets,一种可以动态加载的插件模式。
可视化
PCL基于VTK实现了自己的可视化库,从而方便用户快速查看自己的模型,不管这种模型是通过参数公式设定还是从点云而来。
可视化库也提供了渲染(rendering)以及处理PCD的方法等。使用可视化库的一般流程如下:
using namespace pcl visualization;
PCLVisualizer p (“Test”);
PointCloudColorHandlerRandom handler (cloud);
p.addPointCloud (cloud, handler, ”cloud random”);
p.spin ();
p.removePointCloud (”cloud random”);
PointCloudGeometryHandlerSurfaceNormal handler2 (cloud);
p.addPointCloud (cloud, handler2, ”cloud random”);
p.spin ();
贡献代码的好处
使用开源库的用户会遇到两个问题:
- 有新的需求,而开源库还没有更新
- 功能有Bug,但是没有fix
这个时候如果你完成了上述工作,那么别人也许会从中受益。换个角度,如果每个人碰到这种情况都采取这种处理方式呢?
总而言之,开源项目,就是大家合作一起做一件事,我为人人,人人为我。
再引用Linus法则“given enough eyeballs, all bugs are shallow”,贡献你的代码给大家阅读,你的代码会面临挑战,会促使你不断提高自己的代码质量。还有,程序员的荣誉和成就感,这些也是参与其中才能体会到的。
当然,每个人的情况不一样,就不一一列举啦。
Next 将会介绍如何着手贡献一个具体的功能源码以及介绍PCL的源码风格