4、PCL点云库入门:PCL库安装与配置、PCL核心模块介绍、PCL点云类型转换、PCL可视化基础
说实话,很多做激光雷达的朋友一开始都绕不开PCL这个库。PCL全称Point Cloud Library,是点云处理领域的事实标准。我当年刚接触点云时,第一件事就是跟PCL死磕——安装、编译、踩坑、再编译……嗯,今天我就把这些经验掰开揉碎讲给你听。
4.1 PCL库安装与配置
安装PCL,说白了就两条路:要么用包管理器一键安装,要么源码编译。我个人建议初学者走第一条路,省心。
4.1.1 Ubuntu系统下的安装
如果你用的是Ubuntu,那最简单了。打开终端,敲几行命令就行:
sudo apt-get update
sudo apt-get install libpcl-dev pcl-tools
装完之后,验证一下:
pcl_viewer --help
如果能看到帮助信息,说明装好了。我在项目中遇到过一个问题——装完PCL后找不到头文件。后来发现是版本冲突。建议你装之前先看看系统里有没有旧版本:
dpkg -l | grep pcl
4.1.2 Windows下的安装
Windows下我推荐用vcpkg。你想想看,手动配置环境变量多麻烦?vcpkg一键搞定:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg install pcl:x64-windows
装完之后,在CMakeLists.txt里加上:
find_package(PCL REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
target_link_libraries(your_project ${PCL_LIBRARIES})
4.1.3 macOS下的安装
macOS用户用Homebrew:
brew install pcl
我个人习惯在macOS上做原型开发,因为调试方便。但要注意,M1芯片的Mac有些PCL模块编译会报错,建议用Rosetta2模式。
4.2 PCL核心模块介绍
PCL的模块划分很清晰。我画了一张图,帮你快速建立整体认知:
这张图里,我重点标出了几个你一定会用到的模块:
- Filters模块:说白了就是给点云"洗澡"。去掉离群点、降采样、裁剪ROI区域,都靠它。我在做路沿检测时,先用直通滤波把范围卡到路面区域,再用体素滤波降采样,速度能快3倍。
- Features模块:计算点云的特征描述子。比如法线、PFH、FPFH。这些是后续配准和识别的基础。
- Segmentation模块:把点云分成不同的区域。地面分割、欧式聚类分割,自动驾驶里天天用。
- Registration模块:点云配准。ICP算法是经典中的经典,多帧点云拼接全靠它。
- Visualization模块:可视化。调试时离不开它。
4.3 PCL点云类型转换
PCL里点云类型很多,最常用的是pcl::PointXYZ和pcl::PointXYZRGB。你想想看,雷达只给xyz坐标,但相机能提供颜色信息,怎么融合?类型转换就派上用场了。
4.3.1 常见点云类型
| 类型 | 字段 | 适用场景 |
|---|---|---|
| PointXYZ | x, y, z | 纯几何点云 |
| PointXYZRGB | x, y, z, r, g, b | 带颜色的点云 |
| PointXYZI | x, y, z, intensity | 带反射强度的点云 |
| PointNormal | x, y, z, normal_x, normal_y, normal_z | 带法线的点云 |
4.3.2 类型转换实战
我举个例子,把PointXYZ转成PointXYZRGB:
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
// 原始点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz(new pcl::PointCloud<pcl::PointXYZ>());
// 目标点云
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_rgb(new pcl::PointCloud<pcl::PointXYZRGB>());
// 转换
pcl::copyPointCloud(*cloud_xyz, *cloud_rgb);
// 给所有点赋红色
for (auto& point : cloud_rgb->points) {
point.r = 255;
point.g = 0;
point.b = 0;
}
copyPointCloud转换时,如果源点云有NaN值,目标点云也会保留NaN。建议转换前先做一步滤波,把无效点去掉。
4.4 PCL可视化基础
可视化是调试的"眼睛"。PCL提供了pcl::visualization::PCLVisualizer,功能很强大。
4.4.1 最简单的可视化
#include <pcl/visualization/cloud_viewer.h>
pcl::visualization::CloudViewer viewer("点云查看器");
viewer.showCloud(cloud_xyz);
while (!viewer.wasStopped()) {
// 保持窗口打开
}
这段代码能跑,但功能有限。我建议你用PCLVisualizer,更灵活:
#include <pcl/visualization/pcl_visualizer.h>
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
viewer->setBackgroundColor(0, 0, 0); // 黑色背景
viewer->addPointCloud<pcl::PointXYZ>(cloud_xyz, "sample cloud");
viewer->setPointCloudRenderingProperties(
pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");
while (!viewer->wasStopped()) {
viewer->spinOnce(100);
}
4.4.2 添加辅助元素
调试时,光看点云不够。我习惯加上坐标系和文字标注:
// 添加坐标系(原点,长度1.0)
viewer->addCoordinateSystem(1.0);
// 添加文字
viewer->addText("原始点云", 10, 10, 20, 1.0, 1.0, 1.0, "text1");
// 添加球体标记
pcl::PointXYZ center(0.0, 0.0, 0.0);
viewer->addSphere(center, 0.1, 1.0, 0.0, 0.0, "sphere1");
viewer->setCameraPosition(0, 0, 5, 0, 0, 0);来调整视角。
4.4.3 多视角可视化
有时候需要对比原始点云和处理后的点云。PCL支持多视口:
int v1(0), v2(1);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 左半屏
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2); // 右半屏
viewer->addPointCloud(cloud_original, "original", v1);
viewer->addPointCloud(cloud_filtered, "filtered", v2);
嗯,这个功能我在做滤波效果对比时天天用。左边看原始点云,右边看滤波后的,效果一目了然。
好了,PCL入门就讲到这里。记住一句话:PCL是个工具,别怕踩坑,多写代码多调试,慢慢就熟了。