基于3D激光点云的障碍物检测与跟踪---(1)体素下采样、ROI 区域裁剪与地面点云分割

在机器人系统中,激光雷达(LiDAR)产生的原始点云数据量非常庞大,往往包含几十万到上百万个点。如果直接用于聚类、检测、匹配,将造成计算负担过重、实时性降低。

因此,我们需要对点云进行滤波与预处理(Filtering & Preprocessing),以去除无效点、降低数据量、增强关键特征。

本文将系统介绍点云处理中的三个核心步骤:

  1. 体素下采样(VoxelGrid Downsampling)
  2. ROI 区域裁剪(Region of Interest Cropping)
  3. 地面点云分割(Ground Segmentation)

一、体素下采样(VoxelGrid Downsampling)

1.1 为什么要进行下采样

激光雷达采样密度高、数据量大,若直接使用原始点云:

  • 计算量大,影响实时性;
  • 相邻点空间分布过密,信息冗余;
  • 聚类或拟合算法耗时严重。

体素下采样(VoxelGrid) 的核心思想是:

将点云划分为立方体小格(Voxel),在每个体素中仅保留一个代表点(通常为该体素内所有点的重心)。

这样既能大幅减少点云数量,又能保持整体几何结构。


1.2 实现原理

假设每个体素的边长为 (leaf_size_x, leaf_size_y, leaf_size_z)

  • 将整个点云空间划分为体素网格;
  • 对每个体素内的所有点,计算平均坐标;
  • 以该平均点代表该体素。

1.3 核心代码

cpp 复制代码
  voxel.setInputCloud(cloud_in); // 输入点云
  voxel.setLeafSize(0.1f, 0.1f, 0.1f);  // 体素大小(单位: 米)
  voxel.filter(*cloud_filtered);

💡 参数说明:

  • setLeafSize(0.1, 0.1, 0.1) 表示体素边长为 10 cm;
  • 数值越大,点云越稀疏,计算速度更快但细节损失更多;
  • 常用范围为 0.05~0.2m

1.4 效果对比

阶段 点云数量 特征保持 耗时
原始点云 120,000 ✅ 完整 ❌ 高
下采样后 35,000 ✅ 形状保持 ✅ 快速

结果:在保持主要结构形状的同时,点云数量减少约 70%,显著提升后续处理效率。


二、ROI 区域裁剪(Region of Interest Cropping)

2.1 目的

激光雷达扫描范围广,但我们通常只关心机器人周围一定区域 (如前方 10 米内)。

ROI 区域裁剪的目标是:

去除远距离、顶部、地面下方等无关区域,仅保留机器人周围感兴趣点云。


2.2 实现思路

  1. 使用 PassThrough Filter 对 x/y/z 轴设置范围;
  2. 或使用 CropBox Filter 定义一个三维包围盒裁剪点云。

2.3 核心代码

cpp 复制代码
  // 方法一:Z轴直通滤波,去掉地面以下点
  pass.setInputCloud(cloud_in);
  pass.setFilterFieldName("z");
  pass.setFilterLimits(-1.5, 2.0);
  pass.filter(*cloud_roi);

  // 方法二:使用CropBox定义感兴趣区域
  crop.setInputCloud(cloud_roi);
  Eigen::Vector4f min_point(-10.0, -10.0, -0.5, 1.0);
  Eigen::Vector4f max_point(10.0, 10.0, 1.0, 1.0);
  crop.setMin(min_point);
  crop.setMax(max_point);
  crop.filter(*cloud_roi);

三、地面点云分割(Ground Segmentation)

3.1 目标与原理

在经过下采样与裁剪后,点云中仍包含大量地面点。

这些地面点若不去除,会被聚类算法错误地识别为障碍物。

因此,我们需要进行地面分割。


3.2 RANSAC 平面拟合法

RANSAC(随机采样一致性)是最常用的地面拟合方法。

其基本步骤:

  1. 随机选取若干点;
  2. 拟合平面模型;
  3. 判断其他点是否为内点;
  4. 选取内点数最多的模型作为地面平面。

3.3 核心代码

cpp 复制代码
  seg.setOptimizeCoefficients(true);
  seg.setModelType(pcl::SACMODEL_PLANE);
  seg.setMethodType(pcl::SAC_RANSAC); // 使用 RANSAC 随机采样一致性方法
  seg.setMaxIterations(max_iterations); // 最大迭代次数
  seg.setDistanceThreshold(distance_thresh);  // 地面拟合容差
  seg.setInputCloud(cloud_in);
  seg.segment(*inliers, *coefficients); // 保存平面模型的参数 [a, b, c, d](即平面方程:ax + by + cz + d = 0)

  // 提取地面与非地面点
  extract.setInputCloud(cloud_in);
  extract.setIndices(inliers); // 保存属于拟合平面的点索引
  extract.setNegative(false);
  extract.filter(*cloud_ground); // 提取地面点云

  extract.setNegative(true);
  extract.filter(*cloud_non_ground); // 提取非地面点云

四、总结

模块 主要作用 典型方法 特点
体素下采样 降低点云密度、提升实时性 VoxelGrid 结构保持好
ROI 裁剪 去除远处与无关点 CropBox/PassThrough 减少冗余
地面分割 去除地面点,提高聚类精度 RANSAC 稳定可靠

经过这三个步骤,点云数据量减少超过 80%,同时保持几何结构完整性,为后续的目标检测、聚类与跟踪奠定坚实基础。

相关推荐
郭庆汝16 小时前
(二)自然语言处理笔记——Seq2Seq架构、注意力机制
人工智能·笔记·自然语言处理
墨倾许18 小时前
《Windows 11 + Docker:极简DVWA靶场搭建全记录》—— 附详细排错指南与最终解决方案
windows·笔记·网络安全·docker·容器·靶场
WPG大大通18 小时前
【经验分享】Genio 520/Genio720未使用引脚处理方法
经验分享·笔记·信号处理·模块测试·usb·功能模块
xwz小王子18 小时前
PerAct2:机器人双臂操作任务的基准测试和学习
学习·机器人
机器人行业研究员18 小时前
当机器人学会了“知轻重”:六维力传感器和关节力传感器如何重塑餐饮体验
机器人·人机交互·六维力传感器·关节力传感器
yongshao819 小时前
KUKA机械臂使用EthernetKRL配置与C#上位机实现TCP通讯
tcp/ip·机器人·c#·信息与通信
d111111111d19 小时前
STM32外设学习--DMA直接存储器读取--学习笔记。
笔记·stm32·单片机·嵌入式硬件·学习
搞机械的假程序猿20 小时前
普中51单片机学习笔记-前言
笔记·学习·51单片机
马拉AI1 天前
ICLR 2026 前瞻 | 邱锡鹏团队再发力:ROBOOMNI让机器人会“察言观色“,主动帮你解决需求!
机器人·邱锡鹏
9ilk1 天前
【基于one-loop-per-thread的高并发服务器】--- 自主实现HttpServer
linux·运维·服务器·c++·笔记·后端