PCL—— PCL库的简单使用

Posted yuan〇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PCL—— PCL库的简单使用相关的知识,希望对你有一定的参考价值。


文章目录

1. 激光雷达基本概念

本文只是简要介绍激光雷达的相关概念,更多请见下面几篇文章:

  1. Apollo星火计划学习笔记——第六讲上自动驾驶感知基础(I)
  2. 自动驾驶感知——激光雷达物体检测算法
  3. 自动驾驶感知——激光雷达基本概念|激光雷达点云|激光雷达的标定

1.1 激光雷达特点

激光探测及测距系统(Light Detection and Ranging,LiDAR)

  • 激光雷达是一种通过发射激光束探测目标的位置、速度等特征量的雷达系统
  • 激光波段位于0.5μm-10μm,以光电探测器为接收器件,以光学望远镜为天线。

特点
• 角分辨率、距离分辨率高
• 抗干扰能力强
• 三维坐标、反射率
• 车体积小、质量轻

1.2 激光雷达点云定义

    点云是激光雷达获取的三维场景信息的数据存储形式,不同于图像数据,点云由空间中一系列离散的点组成,并记录了这些点相对于激光雷达自身坐标系的三维坐标与反射率

  • 一帧点云数据(包含N个点)可表示为 x i , y i , z i , r i i = 1 N \\ x_i,y_i,z_i,r_i\\ _i = 1^N xi,yi,zi,rii=1N
  • 其中 ( x i , y i , z i ) (x_i, y_i, z_i) (xi,yi,zi)第个点在激光雷达坐标系下的坐标, r i r_i ri
    该点的反射率。

2. 常用点云处理工具PCL(Point Cloud Library)

PCL 起初是 ROS(Robot Operating System )下由来自斯坦福大学的年轻博士Radu等人维护和开发的开源项目。主要应用于机器人研究应用领域,随着各个算法模块的积累,于 2011 年独立出来,正式与全球 3D信息获取处理的同行一起,组建了强大的开发维护团队,以多所知名大学、研究所和相关硬件、软件公司为主。截止目前 , 发展非常迅速,不断有新的研究机构等加入,在 Willow Garage,Nvidia, Google, Toyota, Trimble, Urban Robotics, Honda Research Institute 等多个全球知名公司的资金支持下,不断提出新的开发计划,代码更新非常活跃 , 至今(2019年10月)从 1.0 版本已经发布到 1.9.1 版本。

2.1 PCL相关资料

PCL官网——https://pointclouds.org/documentation/

PCL库基本架构如下图所示

PCL安装教程——Ubuntu18.04编译安装PCL点云库(稳定可靠)
PCL相关教程与资料

  1. 一位博主的笔记https://www.yuque.com/huangzhongqing/pcl/
  2. 官方教程——https://pcl.readthedocs.io/projects/tutorials/en/master/
  3. 《点云库PCL从入门到精通》
  4. 黑马机器人——https://robot.czxy.com/docs/pcl/
  5. PCL(Point Cloud Library)学习指南&资料推荐(2023版)

2.2 点云PCD文件格式文件头

PCD文件格式包括二进制与ASCII码,二进制格式存储空间小。

# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7 #指定PCD文件版本
FIELDS x y z intensity timestamp #指定一个点可以有的每一个维度和字段的名字:坐标、反射强度、时间戳
SIZE 4 4 4 1 8   #FIELDS字段字节大小
TYPE F F F U F   #用一个字符指定每一个维度的类型
COUNT 1 1 1 1 1  #指定每一个维度包含的元素数目
WIDTH 94476   #用点的数量表示点云数据集的宽度
HEIGHT 1   #用点的数目表示点云数据集的高度
VIEWPOINT 0 0 0 1 0 0 0  #指定数据集中点云的获取视点
POINTS 94476  #指定点云中点的总数
DATA binary_compressed #指定存储点云数据的数据类型

ASCII码形式

二进制形式

2.3 点云的有序和无序

无序点云是指将点云中点的坐标、反射强度、时间戳等信息直接堆放存储。

有序点云数据集意味着点云是类似于图像(或者矩阵)的结构,数据分为行和列。有序数据集的优势在于,预先了解相邻点(和像素点类似)的关系,邻域操作更加高效,这样就加速了计算并降低了PCL中某些算法的成本。

3. Vscode 极简环境配置

因为是极简配置,所以只需要对一个c_cpp_properties.json配置文件进行修改。
c_cpp_properties.json


    "configurations": [
        
            "name": "Linux",
            "includePath": [
                "$workspaceFolder/**",
                "/usr/include/pcl-1.8",
                "/usr/include/eigen3",
                "/usr/include",
                "/usr/local/include",
                "/opt/ros/melodic/include"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu11",
            "cppStandard": "gnu++14",
            "intelliSenseMode": "gcc-x64"
        
    ],
    "version": 4

4. 一个简单的例子

创建一个文件夹PCL_test01,并创建一个build文件夹、一个src文件夹与一个CMakeLists.txt。

src中创建test01.cpp

test01.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
 
int
  main (int argc, char** argv)

  pcl::PointCloud<pcl::PointXYZ> cloud;
  
  // Fill in the cloud data
  cloud.width    = 5;
  cloud.height   = 1;
  cloud.is_dense = true;
  cloud.points.resize (cloud.width * cloud.height);
 
  for (size_t i = 0; i < cloud.points.size (); ++i)
  
    cloud.points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
  
 
  pcl::io::savePCDFileASCII ("test_pcd.pcd", cloud);
  std::cerr << "Saved " << cloud.points.size () << " data points to test_pcd.pcd." << std::endl;
 
  for (size_t i = 0; i < cloud.points.size (); ++i)
    std::cerr << "    " << cloud.points[i].x << " " << cloud.points[i].y << " " << cloud.points[i].z << std::endl;
 
  return (0);

对CMakeLists.txt进行填写:

cmake_minimum_required(VERSION 3.10.2)
project(PCL_TEST01) # 项目名称
set(CMAKE_CXX_STANDARD 11) # C++版本

# 设置输出根目录
set(OUTPUT_DIRECTORY_ROOT $CMAKE_CURRENT_SOURCE_DIR/$CMAKE_BUILD_TYPE)
# 设置可执行程序输出到bin目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "$OUTPUT_DIRECTORY_ROOT/bin" CACHE PATH "Runtime directory" FORCE)

find_package(PCL REQUIRED)
# 包含头文件目录
include_directories($PCL_INCLUDE_DIRS)
# 设置依赖库链接目录
link_directories($PCL_LIBRARY_DIRS)
# 添加预处理器和编译器标记
add_definitions($PCL_DEFINITIONS)

add_executable(test01 src/test01.cpp)
target_link_libraries(test01 $PCL_LIBRARIES)

完成之后,cd到build文件夹,先cmake … 再make.

cd YOUR_BUILD_PATH
cmake ..
make

编译成功后,会在bin中看到test01的可执行文件.
执行该文件

./test01


再输入

pcl_viewer test_pcd.pcd
The viewer window provides interactive commands; for help, press 'h' or 'H' from within the window.
> Loading test_pcd.pcd [done, 157 ms : 5 points]
Available dimensions: x y z

可以在pcl_viewer中看到五个点云.

5. 简单的可视化实现

test02.cpp

#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>

int main(int argc, char **argv) 

    // 创建PointCloud的智能指针
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    // 加载pcd文件到cloud
    pcl::io::loadPCDFile("../data/result.pcd", *cloud);
    pcl::visualization::CloudViewer viewer("Cloud Viewer");
    //这里会一直阻塞直到点云被渲染
    viewer.showCloud(cloud);

    // 循环判断是否退出
    while (!viewer.wasStopped()) 
        // 你可以在这里对点云做很多处理
    
    return 0;

在Vscode中可能会遇到#include <pcl/visualization/cloud_viewer.h>报错,目前没找到可行的解决方案(有了踢我一下),但并不影响编译。

运行后

想要按照x,y,z,intensity进行渲染,需要用到另一点云视窗类PCLVisualizer.

#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>

int main(int argc, char **argv) 

    // 创建PointCloud的智能指针
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
    // 加载pcd文件到cloud
    if (pcl::io::loadPCDFile("../data/result.pcd", *cloud) == -1)
    
        std::cout << "Could not load pcd file!" << std::endl;
        return -1;
    
    pcl::visualization::PCLVisualizer viewer("Cloud Viewer");
    //背景颜色设置
    viewer.setBackgroundColor(0, 0, 0);
    //按照z字段进行渲染
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> fildColor(cloud, "z");
    //显示点云,其中fildColor为颜色显示
    viewer.addPointCloud<pcl::PointXYZI>(cloud, fildColor, "sample");
    //设置点云大小
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample");

    // 循环判断是否退出
    while (!viewer.wasStopped()) 
        viewer.spinOnce();
    
    return 0;

按x轴进行渲染

按y轴进行渲染

按z轴进行渲染

按intensity渲染

静态构建 PCL 库

【中文标题】静态构建 PCL 库【英文标题】:Building PCL library statically 【发布时间】:2014-06-03 09:20:13 【问题描述】:

我目前正在尝试从仅适用于静态库的相机中收集数据。 然后我必须静态安装 PCL。由于动态版本没有一体化套件,因此我使用 Cmake 手动完成。构建成功,但即使我在 Cmakelists "set(PCL_SHARED_LIBS OFF) " 中设置了选项,PCL 仍然是动态构建的。我试过这个技巧http://www.pcl-users.org/How-to-build-PCL-statically-td4027660.html,但我仍然有动态库。

如何构建静态版本的 PCL?

【问题讨论】:

【参考方案1】:

您可以在 CMake GUI 中修改缓存值。您永远不需要手动修改缓存文件。如果您没有看到 PCL_SHARED_LIBS 变量,您可能需要选中“高级”复选框。

还描述了in the PCL documentation:

【讨论】:

以上是关于PCL—— PCL库的简单使用的主要内容,如果未能解决你的问题,请参考以下文章

Ubuntu16.04下PCL点云库的安装及使用demo

静态构建 PCL 库

qt+pcl点云库

PCL Show Point Cloud 显示点云

Xamarin Forms PCL - webrequest 的干净和简单的方法?

pcl之using pcl in your own project