首页IT科技点云库pcl教程(学习笔记:点云库PCL(Point Cloud Library )介绍)

点云库pcl教程(学习笔记:点云库PCL(Point Cloud Library )介绍)

时间2025-08-03 16:13:10分类IT科技浏览6356
导读:本文简要介绍点云库(PCL ,一个用于处理2D和3D数据的开源库,如激光雷达点云。 通过熟悉使用PCL的一些基础知识,以便后续使用PCL进行定位。主要涵盖以下内容:...

本文简要介绍点云库(PCL)               ,一个用于处理2D和3D数据的开源库                       ,如激光雷达点云               。 通过熟悉使用PCL的一些基础知识        ,以便后续使用PCL进行定位                       。主要涵盖以下内容:

点云数据Point Cloud Data(PCD)文件

点云库The Point Cloud Library(PCL)

PCL查看器(Viewer)

在PCL中创建和使用激光雷达对象

模板Templates和不同的点云

调整激光雷达参数 检查PCL中的点云

一               、点云数据(PCD)文件

激光雷达数据的存储格式称为点云数据(PCD)               ,pcd文件是笛卡尔坐标(x,y,z)和强度值i的列表                       ,是在每一次扫描环境之后的单个快照        。这意味着对于VLP 64激光雷达        ,pcd文件将有大约256,000 (x,y,z,i)值       。

一个城市街区的PCD       ,停着的汽车                       ,和一辆路过的货车                       。强度值以不同的颜色显示                。中间黑色区域是装有激光雷达传感器的汽车所在的位置       。

PCD坐标

点云数据的坐标系与汽车的本地坐标系相同                      。在这个坐标系中               ,x轴指向汽车的前部       ,y轴指向汽车的左侧                。由于这个坐标系采用右手定则                       ,坐标系z轴指向汽车上方。

二                       、点云库PCL

在本课中学习处理点云数据以发现障碍物                      。所有的代码都将在c++环境中完成               ,PCL是一个用于处理点云的开源c++库,使用它来可视化数据        、呈现形状                       ,以及一些内置处理功能                       。在这里可以找到PCL的一些文档:Point Cloud Library | The Point Cloud Library (PCL) is a standalone, large scale, open project for 2D/3D image and point cloud processing.

PCL在机器人社区中被广泛用于处理点云数据                       ,网上有许多使用它的教程。PCL中有许多内置函数可以帮助检测障碍,如分割       、提取和聚类               。

三                       、启动代码

所有代码(以及关于障碍物检测方面的内容)都包含在GitHub存储库中,可以克隆repo               ,并参照README在电脑上运行                       。参考链接:GitHub - udacity/SFND_Lidar_Obstacle_Detection        。 主要包含两个主文件                       ,即environment.cpp和processPointClouds.cpp               。environment.cpp文件包含主函数        ,生成可运行的执行文件                       。processPointClouds.cpp文件包含用于处理pcd的所有函数的占位符        。 另外还有sensors/lidar.h               ,用于模拟激光雷达感知并创建点云数据;render.cpp和render.h                       ,它们有将对象渲染到屏幕上的功能       。

代码结构

顶层:CMakeLists.txt  

Readme

src /

   render/

      box.h -盒子对象的结构定义

      render.h

      render.cpp -这个文件和头文件一起定义了渲染对象的类和方法                       。

   sensors/

      data / -该目录包含本文使用的PCD数据                。

      lidar.h -具有使用射线创建pcd的功能       。

   environment.cpp -主文件:使用PCL查看器        ,处理和可视化pcd                      。

   processPointClouds.h

   processPointClouds.cpp -用于过滤                、分段       、集群                      、装箱                、加载和保存pcd的函数                。

四、编译激光雷达模拟器

在Ubuntu环境(Ubuntu 16.04)下编译指引 

克隆github repo-https://github.com/udacity/SFND_Lidar_Obstacle_Detection :

cd ~ git clone https://github.com/udacity/SFND_Lidar_Obstacle_Detection.git

编辑CMakeLists.txt如下:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR) add_definitions(-std=c++14) set(CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS, "${CXX_FLAGS}") project(playback) find_package(PCL 1.11 REQUIRED) include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS}) list(REMOVE_ITEM PCL_LIBRARIES "vtkproj4") add_executable (environment src/environment.cpp src/render/render.cpp src/processPointClouds.cpp) target_link_libraries (environment ${PCL_LIBRARIES})

    3.在终端中执行以下命令

sudo apt install libpcl-dev cd ~/SFND_Lidar_Obstacle_Detection mkdir build && cd build cmake .. make ./environment

执行./environment,看到一个弹出的窗口       ,图片如下:

 一个简单的高速公路模拟环境                       ,中间车道上的车是绿色的(可自定义的车)               ,其他交通车辆是蓝色的。所有内容都使用带有简单框                      、线条和颜色的PCL进行呈现                      。可以使用鼠标在环境中移动       ,试着按住鼠标左键绕着场景旋转,按住鼠标中键移动场景;若要缩放                       ,移动时使用鼠标中滚动键或鼠标右键                       。

五                       、PCL查看器

在environment.cpp中创建了一个pcl查看器               ,查看器用于处理屏幕上所有对象的可视化。在environment.cpp中使用pcl查看器的函数是initCamera和initHighway,initCamera函数用于在窗口中设置不同的观察角度                       ,有5种不同的选择:XY, TopDown, Side和FPS---XY提供45度视角                       ,FPS则是第一人称视角,给人一种坐在汽车驾驶座上的感觉               。 此外               ,渲染函数也大量使用了查看器                       ,注意viewer通常作为引用传入                       。这样        ,流程就更精简了               ,因为不需要返回任何东西        。

六、创建激光雷达对象 lidar对象由src/sensors/lidar.h的头文件定义                       ,包含在environment.cpp的顶部               。environment.cpp中还有一个simpleHighway函数        ,用于接受PCL可视化器查看器的引用参数                       。

在simpleHighway函数中实例化一个指向Lidar对象的指针        。使用new关键字在堆上创建Lidar指针对象       。Lidar构造函数有两个参数:汽车和地面的坡度——这些参数对于光线碰撞建模是必要的                       。创建的Lidar对象的斜率应为0                。

请注意

激光雷达参数对建模射线碰撞是必要的       。激光雷达对象将保存点云数据       ,容量可能非常大                      。通过在堆上实例化                       ,我们可以使用比堆栈上2MB更多的内存                。但是               ,在堆上查找对象需要更长的时间       ,而堆栈查找非常快。

在environment.cpp                       ,simpleHighway函数中:

/ TODO: Create lidar sensor Lidar* lidar = new Lidar(cars, 0);

七               、使用激光雷达对象

要进一步使用新创建的Lidar对象               ,请查看src/sensors/ Lidar .h,查看所有内容是如何定义的                      。在这个头文件中                       ,射线对象被定义                       。激光雷达将利用这些射线,进行射线投射来感知周围的环境。Lidar结构内的扫描函数执行射线投射               。

现在调用Lidar扫描函数                       ,看看激光雷达射线是什么样子的                       。回到environment文件中,在调用Lidar构造函数之后               ,可以使用scan函数                       ,呈现激光雷达射线        。

激光雷达传感

要创建点云        ,请在lidar对象上调用lidar scan()方法               。

结果存储在一个PointCloud指针对象中               ,pcl::PointCloud::Ptr

PointCloud的点类型将是pcl::PointXYZ                       。

使用生成的PointCloud指针调用renderRays函数        。

请注意

PointCloud的模板语法类似于向量或其他标准容器库的语法: ContainerName<ObjectName>       。

来自PointCloud的Ptr类型表明对象实际上是一个指针—一个包含点云对象的内存地址的32位整数                       。pcl中的许多函数使用点云指针作为参数                       ,因此以这种形式返回inputCloud很方便                。

renderRays函数在src/render中定义       。它包含允许向pcl查看器呈现点和形状的函数                      。在查看器使用它来渲染激光雷达射线作为线段                。

renderRays函数的参数是viewer        ,通过引用传入。这意味着renderRays函数体中对查看器的任何更改       ,都会直接影响函数范围外的查看器                      。激光雷达的位置也得到传递                       ,以及扫描函数生成的点云                       。PointCloud的点类型将是pcl::PointXYZ。我们还会讲到一些其他不同类型的点云               。

在environment.cpp中               ,在simpleHighway函数中       ,在前面的lidar对象实例化之后再添加两行:

// TODO: Create lidar sensor Lidar* lidar = new Lidar(cars, 0); pcl::PointCloud<pcl::PointXYZ>::Ptr inputCloud = lidar->scan(); renderRays(viewer, lidar->position, inputCloud);

 八                       、模板以及不同的点云数据

为什么使用模板?

之前使用的激光雷达扫描函数产生了一个带有pcl::PointXYZ点的pcl PointCloud对象                       。对象使用模板是因为有许多不同类型的点云:一些是3D的                       ,一些是2D的               ,一些包括颜色和强度        。这里使用的是普通的3D点云,所以使用了PointXYZ               。然而                       ,也有一些点具有强度分量                       。 模板可以自动完成这个过程                       ,而不是定义两个单独的函数,一个带有PointXYZ的参数               ,另一个带有PointXYZI的参数        。对于模板                       ,只需要编写一次函数        ,并像使用参数一样使用模板来指定点类型       。

模板和指针

如果您以前没有使用过带有指针的模板               ,那么您可能在代码中注意到                       ,每当使用依赖于模板的指针时        ,都会使用typename                       。例如这里的函数签名:

typename pcl::PointCloud<PointT>::Ptr ProcessPointClouds<PointT>::FilterCloud(typename pcl::PointCloud<PointT>::Ptr cloud, float filterRes, Eigen::Vector4f minPoint, Eigen::Vector4f maxPoint)

 这样做的原因如下:给定一段带有类型名参数的代码       ,如pcl::PointCloud<PointT>::Ptr                       ,在不知道类型名参数的值的情况下               ,编译器无法确定这段代码是值还是类型                。编译器将假定代码代表一个值       。如果代码实际上表示typename       ,则需要指定typename                      。

九        、调整激光雷达参数

你可以围绕场景旋转和移动                       ,以看到投射出来的不同光线                。然而               ,当前的激光雷达设置会限制你的操作。分辨率很低,从场景中看到                       ,只有一条射线接触到一辆汽车                      。所以提高激光雷达的分辨率                       ,就能清楚地看到周围的其他车辆                       。

包括增加最小距离,就不会把与车顶的接触点包括在内;以及提高水平和垂直角度的分辨率和添加噪音。添加的噪声实际上是相当高的               ,因为单位是米                       ,但会产生更有趣和更真实的点数据在场景中               。可以完全自由地试验和调整这些激光雷达超参数!

通过增加垂直层数和z轴周围的角度分辨率来提高激光雷达的分辨率                       。

numLayers:从3改为8        。

horizontalLayerIncrement:从pi/6改变为pi/64               。

将minDistance(最小距离)设置为5(米)        ,以移除车顶上的点                       。

添加噪音               ,0.2左右可以得到更有趣的pcd        。

完成以上设置后                       ,输出如下图所示:

提高激光雷达范围

十               、检测点云 现在可以看到激光雷达射线的样子了        ,那么将要使用和处理的实际点云数据呢?其实       ,可以在渲染中使用renderPointCloud函数查看点云数据                       ,也可以选择关闭高速公路场景的渲染               ,这样就可以看到点云本身的样子       。

上图中的结果是无噪声的       ,激光雷达minDistance设置为零                       。当加大激光雷达minDistance                       ,可以移除上面击中车顶的点               ,因为这些点不能帮助探测其他车辆                。此外,一些噪声方差有助于创建更有趣的点云                       ,添加噪声将帮助开发更健壮的点处理功能       。

要做到以上效果                       ,在simpleHighway函数中调用renderPointCloud而不是renderRays                      。

通过在environment.cpp中将renderScene设置为false,可以无障碍地查看点云                。

完成后               ,输出应该如下图所示:

 模拟PCD

在environment.cpp中                       ,在simpleHighway中        ,删除之前的renderRays调用               ,取而代之的是使用renderPointCloud:

Lidar* lidar = new Lidar(cars, 0); pcl::PointCloud<pcl::PointXYZ>::Ptr inputCloud = lidar->scan(); //renderRays(viewer, lidar->position, inputCloud); renderPointCloud(viewer, inputCloud, "inputCloud"); // You can also use other names than just "inputCloud"

另外                       ,在函数中        ,修改renderScene来隐藏对象边界:

// RENDER OPTIONS bool renderScene = false;

十一                       、总结 通过本文       ,了解了以下内容:

点云数据(PCD)文件

点云库(PCL)

PCL查看器

在PCL中创建和使用激光雷达对象

模板以及不同的点云

调整激光雷达参数

检测PCL中的点云

 

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
网站权重对应的等级(网站权重的查询工具有哪些) 如何利用网站更新来带动网站收录?(掌握这些秘诀,让您的网站飞速成长!)