4、点云预处理:离群点滤除、体素滤波、直通滤波

各位同学,咱们今天聊聊点云预处理。说实话,很多做飞控的朋友拿到激光雷达数据,第一反应就是直接往上怼算法。我当年也这么干过,结果嘛……嗯,炸机了。后来才明白,原始点云就像一块刚从矿里挖出来的石头,杂质太多,不经过打磨根本没法用。

预处理做得好,后面的定位、建图、避障才能稳。今天我就把三个最常用的滤波手段掰开揉碎了讲给你听。

4.1 离群点滤除:把“野点”揪出来

什么叫离群点?说白了就是那些明显不合理的点。比如你扫描一面墙,结果墙外面突然飘着一个孤零零的点——这大概率是传感器噪声或者多路径反射造成的。

我在项目中遇到过最典型的情况:无人机在树林里飞行,树叶晃动导致雷达打到半空中的水滴或者昆虫,这些点如果不去掉,飞控会以为前方有障碍物,然后莫名其妙地急刹车。

常用的方法叫统计滤波。思路很简单:

  • 对每个点,计算它到周围K个邻居的平均距离
  • 如果这个平均距离超出了全局均值的某个标准差范围,就干掉它

代码实现也不复杂,我贴一段我常用的PCL代码:

// 统计离群点滤除
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud(cloud);
sor.setMeanK(50);          // 邻居点数
sor.setStddevMulThresh(1.0); // 标准差倍数
sor.filter(*cloud_filtered);
我的经验:MeanK设50左右比较稳妥,太大容易把边缘点误删,太小又滤不干净。标准差倍数我一般设1.0~1.5,环境越嘈杂倍数越大。

4.2 体素滤波:给点云“减肥”

你想想看,一个16线激光雷达每秒能产生30万个点,32线、64线就更夸张了。这么多点直接扔给飞控,算力根本扛不住。体素滤波就是用来降采样的。

它的原理特别直观:把空间划分成一个个小立方体(体素),每个立方体里只保留一个点(通常是重心点)。体素越大,点云越稀疏,计算量越小,但细节损失也越大。

我习惯用0.1m的体素尺寸做预处理,既能保留环境轮廓,又能把点云量压缩到原来的十分之一左右。代码长这样:

// 体素滤波降采样
pcl::VoxelGrid<pcl::PointXYZ> vg;
vg.setInputCloud(cloud_filtered);
vg.setLeafSize(0.1f, 0.1f, 0.1f); // 体素边长0.1米
vg.filter(*cloud_downsampled);
注意:体素尺寸不能设得太大。我曾经为了省算力设成0.5m,结果无人机在狭窄走廊里直接撞墙——因为墙上的细节全被抹平了,飞控以为前方是空旷区域。血的教训啊。

4.3 直通滤波:只保留感兴趣的区域

这个最简单,也最实用。直通滤波就是沿着某个坐标轴切一刀,只保留范围内的点。

比如无人机在2米高度飞行,你根本不需要关心地面以下1米的点,也不需要关心头顶10米以上的点。把范围限定在高度1~3米,既能减少计算量,又能排除地面反射和天空噪声的干扰。

我一般在飞控里同时做X、Y、Z三个方向的直通滤波:

// 直通滤波 - 只保留前方10米,左右5米,高度1~3米
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud(cloud_downsampled);
pass.setFilterFieldName("z");
pass.setFilterLimits(1.0, 3.0);   // 高度范围
pass.filter(*cloud_z);

pass.setInputCloud(cloud_z);
pass.setFilterFieldName("x");
pass.setFilterLimits(0.0, 10.0);  // 前方范围
pass.filter(*cloud_x);

pass.setInputCloud(cloud_x);
pass.setFilterFieldName("y");
pass.setFilterLimits(-5.0, 5.0);  // 左右范围
pass.filter(*cloud_final);

核心逻辑总结:

离群点滤除 → 体素滤波 → 直通滤波,这个顺序我建议不要乱。先去掉噪声,再降采样,最后切出感兴趣区域。每一步都在为下一步减轻负担。

4.4 三种滤波的对比

滤波方法 主要作用 关键参数 计算开销
统计离群点滤除 去除噪声点、飞点 MeanK, StddevMulThresh
体素滤波 降采样、减少数据量 LeafSize
直通滤波 限定空间范围 FilterLimits 极低

你看,这三种滤波各有各的用处。离群点滤除是“清垃圾”,体素滤波是“压缩文件”,直通滤波是“划重点”。三者配合好了,你的点云数据才能又快又准地喂给飞控。

避坑指南:我曾经在雨雾天气测试,离群点滤除的参数死活调不好。后来发现是雨滴造成的密集噪声,统计滤波根本分不清。这种情况我建议先做直通滤波把高度范围卡死,再做体素滤波把雨滴平均掉,最后用离群点滤除收尾。顺序调一下,效果天差地别。

好了,点云预处理这块我就讲这么多。记住一句话:预处理做得好,飞控稳得像老狗;预处理偷懒,炸机就在下一秒。你自己琢磨琢磨是不是这个理儿。

点云预处理流程 原始点云 离群点滤除 去除噪声飞点 体素滤波 降采样压缩 直通滤波 限定空间范围 预处理后点云 关键参数建议 • 离群点滤除:MeanK=50, StddevMulThresh=1.0~1.5 • 体素滤波:LeafSize=0.1m(室内)~0.2m(室外) • 直通滤波:根据飞行高度和任务场景灵活设定 ⚠ 处理顺序不可颠倒:先清噪 → 再压缩 → 最后切范围

专注资料整理