文章目录
- 1. 激光雷达基本概念
- 1.1 激光雷达特点
- 1.2 激光雷达点云定义
- 2. 常用点云处理工具PCL(Point Cloud Library)
- 2.1 PCL相关资料
- 2.2 点云PCD文件格式文件头
- 2.3 点云的有序和无序
- 3. Vscode 极简环境配置
- 4. 一个简单的例子
- 5. 简单的可视化实现
1. 激光雷达基本概念
本文只是简要介绍激光雷达的相关概念,更多请见下面几篇文章:
- Apollo星火计划学习笔记——第六讲上自动驾驶感知基础(I)
- 自动驾驶感知——激光雷达物体检测算法
- 自动驾驶感知——激光雷达基本概念|激光雷达点云|激光雷达的标定
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,ri}i=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相关教程与资料:
- 一位博主的笔记https://www.yuque.com/huangzhongqing/pcl/
- 官方教程——https://pcl.readthedocs.io/projects/tutorials/en/master/
- 《点云库PCL从入门到精通》
- 黑马机器人——https://robot.czxy.com/docs/pcl/
- 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>intmain (int argc, char** argv)
{pcl::PointCloud<pcl::PointXYZ> cloud;// Fill in the cloud datacloud.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文件到cloudpcl::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>
报错,将相关路径配置好即可.如在 c_cpp_properties.json
的includePath
里添上 "/usr/include/vtk-6.3",
运行后
想要按照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文件到cloudif (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渲染