4. 直通滤波:快速裁剪无效区域的利器

做SLAM的人,谁没被定位漂移折磨过?

我记得刚入行那会儿,调试一个AGV的定位系统。车子在仓库里跑得好好的,一到门口就开始抽风——定位数据跳来跳去,轨迹直接画成了鬼画符。排查了半天,发现是门口那堆堆高机的金属货架反射太强,激光雷达扫到那些点,全成了噪声。

当时我师傅走过来,看了一眼点云,说了句:「把没用的区域切掉」。

嗯,这就是直通滤波。

4.1 直通滤波到底在干什么?

说白了,直通滤波就是一把剪刀。

你有一堆三维点云,每个点都有X、Y、Z坐标。直通滤波做的事情很简单:设定一个范围,范围外的点,全扔掉。

比如你的激光雷达装在车顶,高度2米。那2.5米以上的点,大概率是天花板、吊灯、横梁。这些点对定位没什么帮助,反而会引入噪声。一刀切掉,干净利落。

我习惯把直通滤波叫做「第一道防线」。为什么?因为它是所有点云预处理里最快、最直接的方法。不涉及复杂的数学计算,不迭代,不聚类。就是比大小,然后删点。

核心思想: 在指定维度上设定阈值区间,保留区间内的点,剔除区间外的点。

4.2 什么时候该用直通滤波?

你想想看,SLAM系统里哪些场景最需要它?

  • 场景一:固定安装的传感器。比如扫地机器人,激光雷达高度固定。地面以下和天花板以上的点,全是无效数据。
  • 场景二:已知工作区域。比如AGV只在某个车间里跑。车间墙壁以外的点,要么是反射噪声,要么是隔壁车间的干扰。
  • 场景三:去除载体自身。机器人身上的结构件、支架,有时候会被雷达扫到。这些点离传感器太近,而且位置固定,对定位没帮助。

我在项目中遇到过最典型的案例:一个室外无人车,GPS信号弱的时候靠激光雷达定位。结果每次经过一片灌木丛,点云里就多出一堆乱七八糟的叶子点。这些点高度在0.5米到1.5米之间,正好和路沿、障碍物混在一起。后来我在Z轴上做了一个直通滤波,只保留0.2米以下和1.8米以上的点——灌木丛的干扰直接减少了80%。

我的经验: 直通滤波最适合处理「已知固定干扰」的场景。如果干扰源的位置和高度会变化,那就要考虑其他方法了。

4.3 代码实现:三行代码搞定

PCL里实现直通滤波,代码量少得可怜。我直接贴一个我常用的模板:

#include <pcl/filters/passthrough.h>

// 输入点云:cloud_in
// 输出点云:cloud_filtered

pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud(cloud_in);
pass.setFilterFieldName("z");        // 沿Z轴滤波
pass.setFilterLimits(0.0, 2.0);      // 保留0到2米范围
// pass.setFilterLimitsNegative(true); // 如果设为true,则保留范围外的点
pass.filter(*cloud_filtered);

你看,就这么几行。但有几个细节我得提醒你:

  • setFilterFieldName 可以填 "x"、"y"、"z",也可以填强度字段 "intensity"。
  • setFilterLimits 的两个参数是闭区间。也就是说,等于边界值的点也会保留。
  • setFilterLimitsNegative 这个参数很实用。有时候你想保留「范围外」的点,比如只保留地面以下的点,那就把它设为true。

4.4 避坑指南:我曾经踩过的坑

直通滤波虽然简单,但用不好也会翻车。我分享几个真实教训:

坑一:坐标系搞反了

我曾经接手过一个项目,前同事写的代码,在Z轴上做了直通滤波,结果定位一直飘。查了半天才发现——他的雷达安装时旋转了90度,Z轴其实对应的是水平方向。滤波把水平方向上的点切掉了一大半,特征点不够,定位自然就崩了。

教训: 滤波之前,先确认你的点云坐标系。传感器安装角度变了,滤波方向也要跟着变。

坑二:阈值设得太死

有一次做室内定位,我把Z轴滤波范围设成了0.1米到1.9米。结果机器人过门槛的时候,车身抬高了一点,激光雷达扫到的地面点全被切掉了。定位直接丢失。

教训: 阈值要留余量。尤其是移动机器人,车身姿态会变化,滤波范围要覆盖所有可能的工况。

坑三:忘了考虑多帧叠加

SLAM系统里,点云往往是多帧叠加的。如果你在单帧上做了直通滤波,叠加之后某些区域可能点云密度骤降。我见过有人把Z轴滤波设得太窄,结果叠加后的地图上,天花板区域全是空洞。

教训: 如果做多帧叠加,滤波策略要统一。要么每帧都滤波,要么叠加后再滤波,不要混着来。

4.5 直通滤波在SLAM中的定位

直通滤波不是万能的。它解决不了动态物体的干扰,也处理不了离群点。但它有一个无可替代的优势:快。

我做过测试,100万个点的点云,做一次直通滤波只需要几毫秒。相比之下,体素滤波要几十毫秒,统计滤波要上百毫秒。所以在实时性要求高的系统里,直通滤波往往是第一道关卡。

我个人习惯的预处理流程是这样的:

  1. 直通滤波:快速切掉已知的无效区域(天花板、地面、墙壁外)
  2. 体素滤波:降采样,减少计算量
  3. 统计滤波:去除离群点

这个顺序不是随便定的。先做直通滤波,可以大幅减少后续步骤的计算量。你想想看,如果点云里有一半的点都是天花板,先切掉它们,体素滤波和统计滤波的处理时间能省一半。

4.6 本章小结

直通滤波,说白了就是一把快刀。它不聪明,但很实用。在SLAM系统里,它负责把那些「明知道没用」的点快速清理掉,为后续的精细处理腾出空间。

记住三个要点:

  • 用对坐标系——滤波方向要和传感器安装一致
  • 留足余量——阈值别卡得太死,给机器人留点活动空间
  • 放在预处理第一步——先切再降,效率最高

嗯,直通滤波就讲到这里。下一章我们聊聊体素滤波,那个才是真正考验参数调优功底的东西。


可可精品资料库