对于3D点云处理来说,PCL完全是一个模块化的现代C++模板库。其基于以下第三方库:Boost、Eigen、FLANN、VTK、CUDA、OpenNI,QHull,实现点云相关的获取、滤波、分割、配准、检索、特征提取、识别、追踪﹑曲面重建、可视化等。
PCL利用OpenMP,GPU,CUDA等先进高性能计算技术,通过并行化提高程序实时性。K近邻搜索操作的构架是基于FLANN (FastLibrary for ApproximateNearestNeighbors)所实现的,速度也是目前技术中最快的。PCL中的所有模块和算法都是通过Boost共享指针来传送数据,因而避免了多次复制系统中已存在的数据的需要,从0.6版本开始,PCL就已经被移入到Windows,MacOS和 Linux系统,并且在Android系统也已经开始投人使用,这使得 PCL的应用容易移植与多方发布。
从算法的角度,PCL是指纳入了多种操作点云数据的三维处理算法,其中包括过滤、特征估计、表面重建,模型拟合和分割、定位搜索等。每一套算法都是通过基类进行划分的,试图把贯穿整个流水线处理技术的所有常见功能整合在一起,从而保持了整个算法实现过程中的紧凑和结构清晰,提高代码的重用性,简洁可读。在 PCL中一个处理管道的基本接口程序如下:
(1)创建处理对象:(例如过滤﹑特征估计、分割等)。
(2)使用setInputCloud通过输入点云数据,处理模块。
(3)设置算法相关参数。
(4)调用计算(或过滤﹑分割等)得到输出。
为了进一步简化和开发,PCL被分成一系列较小的代码库,使其模块化,以便能够单独编译使用提高可配置性,特别适用于嵌入式处理中:
(1) libpcl filters:如采样、去除离群点﹑特征提取、拟合估计等数据实现过滤器。
(2) libpcl features :实现多种三维特征,如曲面法线﹑曲率、边界点估计、矩不变量、主曲率,PFH和FPFH 特征,旋转图像﹑积分图像,NARF描述子,RIFT,相对标准偏差,数据强度的筛选等。
(3) libpcl I/O:实现数据的输人和输出操作,例如点云数据文件(PCD)的读/写。
(4) libpcl segmentation:实现聚类提取,如通过采样一致性方法对一系列参数模型(如平面,柱面,球面、直线等)进行模型拟合点云分割提取,提取多边形棱镜内部点云等。
(5) libpcl surface:实现表面重建技术,如网格重建、凸包重建、移动最小二乘法平滑等。
(6) libpcl register:实现点云配准方法,如ICP等。
(7) libpclkeypoints :实现不同的关键点的提取方法,这可以用来作为预处理步骤,决定在哪儿提取特征描述符。
(8) libpcl range :实现支持不同点云数据集生成的范围图像。
pcl官方、linux教程
pcl_test.cpp
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv) {
std::cout << "Test PCL !!!" << std::endl;
pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr (new pcl::PointCloud<pcl::PointXYZRGB>);
uint8_t r(255), g(15), b(15);
for (float z(-1.0); z <= 1.0; z += 0.05)
{
for (float angle(0.0); angle <= 360.0; angle += 5.0)
{
pcl::PointXYZRGB point;
point.x = 0.5 * cosf (pcl::deg2rad(angle));
point.y = sinf (pcl::deg2rad(angle));
point.z = z;
uint32_t rgb = (static_cast<uint32_t>(r) << 16 |
static_cast<uint32_t>(g) << 8 | static_cast<uint32_t>(b));
point.rgb = *reinterpret_cast<float*>(&rgb);
point_cloud_ptr->points.push_back (point);
}
if (z < 0.0)
{
r -= 12;
g += 12;
}
else
{
g -= 12;
b += 12;
}
}
point_cloud_ptr->width = (int) point_cloud_ptr->points.size ();
point_cloud_ptr->height = 1;
pcl::visualization::CloudViewer viewer ("test");
viewer.showCloud(point_cloud_ptr);
while (!viewer.wasStopped()){
};
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(pcl_test)
find_package(PCL 1.2 REQUIRED)
include_directories(${
PCL_INCLUDE_DIRS})
link_directories(${
PCL_LIBRARY_DIRS})
add_definitions(${
PCL_DEFINITIONS})
add_executable(pcl_test pcl_test.cpp)
target_link_libraries (pcl_test ${
PCL_LIBRARIES})
将上述两个测试文件复制到下面目录结构下,并新建一个build文件夹:
cd build
cmake ..
make
./pcl_test
cmake_minimum_required(VERSION 2.6)
这是对CMake版本的最低要求,由于做的是非常基础的工程,不需要CMake 2.8或者更高版本中的功能。
project(pcl_test)
这一行为工程命名,同时CMake会自动产生一些有用的CMake变量,例如源代码目录路径变量名为(pcl_test),这些都是CMake在内部根据上面定义的工程名称自动生成的,不需要用户定义,而用户只需要利用project(XX)宏即可引发其他变量的内部定义。
find_package(PCL 1.2 REQUIRED)
这行要求该工程依赖PCL最低1.2的版本,即在CMake配置生成工程文件时,必须找到符合要求的PCL库相关模型所在的库和头文件路径,这里的REQUIRED意味着如果对应的库不能找到,则CMake配置过程将完全失败,因为PCL是模块化的,也可以作如下的要求:
一个组件:find_package(PCL1.3 REQUIRED COMPONENTS io)
多个组件:find_package(PCL1.3 REQUIRED COMPONENTS io common) ,该版本需要至少包含common和I/О两个模块
所有组件:find_package(PCL 1.3 REQUIRED)
下面语句是利用CMake的宏完成对PCL的头文件路径和链接路径变量的配置和添加,即如果缺省下面几句,在生成的过程文件编译时会提示找不到相关头文件错误,或者在链接的时候出现无法解析的外部符号等错误提示。
include_directories($ {PCL_INCLUDE_DIRS})
link_directories($ {PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
在配置CMake时,当CMake找到了安装的PCL,下面相关的包含文件.链接库路径变量等就会自动设置:
PCL_FOUND:如果找到了PCL,被设置为1,否则不设置。
PCL_INCLUDE_DIRS:被设置成PCL安装头文件和依赖头文件的目录。
PCL_LIBRARIES:被设置成所建立和安装的PCL库的文件名。
PCL_LIBRARY_DIRS:被设置成PCL库和第三方依赖文件所在的目录。
PCL_VERSION:所找到的PCL的版本。
PCL_COMPONENTS:列出所有可用组件。
PCL_DEFINITIONS:列出所需要的预处理器定义和编译器标志。
为了让CMake知道包含到自己工程中的外部头文件,需要使用include_directo-ries()宏,在实例中为PCL_INCLUDE_DIRS,精确地包含了我们所需要的PCL相关的头文件,因此CMake 会自动根据找到的PCL安装目录自动搜索PCL所有可能包含的目录。
add_executable(pcl_test pcl_test.cpp)
该句告诉CMake,我们正试图从单个源文件pcl_test.cpp来新建一个名为pcl_test的可执行文件,CMake会注意到后缀(在
Windows平台上为.exe,在UNIX平台上为空)和权限。
target_link_libraries (pcl_test ${PCL_LIBRARIES})
到目前为止,我们仅仅包含了PCL头文件,因此编译器知道我们现在访问所用的方法,我们也需要让链接器知道我们所链接的库,PCL找到库文件由PCL_LI-BRARIES变量指示,剩下的是通过访问target_link_libraries()这个宏来触发链接操作。