资讯动态

激光雷达点云滤波——体素降采样、统计滤波和直通滤波

发布时间:2026/8/7 12:09:43 来源:尧图企业网站定制
上篇讲了3D点云的数据结构、文件格式和基本处理流程。里面提到降采样和滤波是第一步但具体怎么操作、参数怎么选、每种滤波适合什么场景那篇没展开。今天专门讲点云滤波。体素降采样、统计滤波、直通滤波、半径离群点滤波这四种是最常用的。面试时候经常问的不只是你用过哪些滤波而是你为什么选这个滤波、参数怎么定的。之前面试一家做仓储AGV的公司面试官问我你的点云预处理用的什么滤波我说用体素降采样加统计滤波。他追问体素大小怎么选的我说了个0.1米他问为什么不是0.05或者0.2。我当时没答上来后来才知道这个问题考的是你对滤波参数和下游任务之间关系的理解。体素降采样Voxel Grid Filter体素降采样是点云处理的第一步几乎所有项目都会用。原理很简单把三维空间划分成一个个小立方体体素每个体素内的所有点用一个点来代替通常取质心。这样既保留了点云的整体形状又大幅减少了点数。import open3d as o3d pcd o3d.io.read_point_cloud(scan.pcd) print(f原始点数: {len(pcd.points)}) # 体素大小0.1米 downsampled pcd.voxel_down_sample(voxel_size0.1) print(f降采样后点数: {len(downsampled.points)})PCL里的写法#include pcl/filters/voxel_grid.h pcl::VoxelGridpcl::PointXYZ sor; sor.setInputCloud(cloud); sor.setLeafSize(0.1f, 0.1f, 0.1f); sor.filter(*cloud_filtered);体素大小leaf size怎么选这是面试最爱追问的。核心原则体素大小要小于你最关心的最小物体的特征尺寸。比如你要检测的最小障碍物是一个0.3米宽的箱子体素就不能超过0.1米否则箱子的角点可能被平滑掉。如果你做的是大场景建图比如室外道路关心的最小特征是车道线宽度约0.15米体素可以设到0.05-0.1米。另一个考虑是计算量。体素越小保留的点越多后续处理越慢。一个经验值对于实时系统10Hz以上降采样后的点数控制在5万以内比较安全。你可以先用不同体素大小跑几遍看哪个能在保留足够特征的同时满足实时性要求。有个坑要注意体素降采样会破坏点云的有序结构。如果你的原始数据是有序点云organized降采样之后变成无序的了。后续如果要用有序点云的算法比如基于图像投影的方法就得注意这个问题。统计滤波Statistical Outlier Removal统计滤波用来去除离群点。那些因为噪声、反射错误产生的飞点在空间中远离其他点统计滤波能把它们揪出来。原理是这样的对每个点计算它到第k近邻居的平均距离。这个距离在整个点云中大致服从正态分布。如果某个点的平均距离明显大于全局均值超过若干个标准差就认为它是离群点。# Open3D统计滤波 cl, ind downsampled.remove_statistical_outlier( nb_neighbors20, std_ratio2.0 ) inlier_cloud downsampled.select_by_index(ind) outlier_cloud downsampled.select_by_index(ind, invertTrue)PCL版本#include pcl/filters/statistical_outlier_removal.h pcl::StatisticalOutlierRemovalpcl::PointXYZ sor; sor.setInputCloud(cloud); sor.setMeanK(20); // 考虑20个邻居 sor.setStddevMulThresh(2.0); // 2倍标准差阈值 sor.filter(*cloud_filtered);两个关键参数nb_neighbors邻居数k通常取20-50。k越大对正常的定义越宽松滤波越保守。k越小越容易把稀疏区域的正常点也删掉。室内密集环境可以取小一点15-20室外稀疏环境取大一点30-50。std_ratio标准差倍数通常取1.0-3.0。越小滤波越激进越大越保守。室内场景噪声小1.5-2.0就够了。室外场景点分布不均匀建议2.5-3.0否则会误删远处的真实点。面试时候被问参数怎么调不要说凭经验。正确的回答是根据你的场景特点室内/室外、点云密度、噪声水平选一个初始值然后通过实验验证——把滤波前后的点云叠加对比看离群点是否被有效去除、真实点是否被误删。如果下游有检测任务可以用检测精度作为评价指标来选最优参数。直通滤波PassThrough Filter直通滤波是最简单的滤波方式在某个坐标轴方向上设定一个范围范围外的点直接去掉。# 只保留x方向0-10米范围内的点 passthrough downsampled.crop( min_bound(-0.5, -10, -1), max_bound(10, 10, 3) )PCL版本#include pcl/filters/passthrough.h pcl::PassThroughpcl::PointXYZ pass; pass.setInputCloud(cloud); pass.setFilterFieldName(z); pass.setFilterLimits(-0.5, 3.0); // 只保留地面以上0.5m到3m pass.filter(*cloud_filtered);直通滤波看起来简单但非常实用。最常见的用法是去除地面以下和天花板以上的点。室内服务机器人的场景里雷达扫到的点包括地面、桌面、天花板。你只关心0.5米到2.5米高度范围内的障碍物用直通滤波把z轴范围一卡地面和天花板的点就没了。限定感兴趣区域ROI。比如你的机器人只在前进方向10米范围内需要感知后面的点直接裁掉减少后续计算量。去除雷达近身的盲区。3D雷达在近距离比如0.5米以内的测距精度很差而且经常有自身结构比如安装支架产生的虚假点。用直通滤波把近距离区域裁掉简单有效。有个细节直通滤波的边界不要设得太紧。如果你的机器人需要在9.5米处检测到障碍物滤波边界不要设到9.5米至少留0.5米的余量。因为点云本身有噪声边界太紧会把边缘的点切掉导致障碍物看起来比实际小。面试中怎么聊面试官问点云滤波不要只说我用了体素降采样和统计滤波。要把选择的理由讲清楚为什么先直通再降采样减少计算量、体素大小怎么选的根据最小检测目标、统计滤波的参数怎么定的根据场景密度和噪声水平。如果面试官继续问有没有更好的滤波方案你可以提双边滤波保边去噪、移动最小二乘法平滑法线估计一体化、基于深度学习的去噪PointCleanNet等。这些方案更复杂但在特定场景下效果更好。补充一个调参的实用技巧不要只靠肉眼看效果来调参。写一个简单的参数扫描脚本遍历不同参数组合把每种组合的滤波前后点数比、处理耗时、以及下游任务比如聚类数量、检测精度的结果都记录下来画成表格或曲线图。这样你能客观地找到最优参数而不是凭感觉瞎猜。我一般用Python的itertools.product来生成参数组合跑完自动出报告。下一篇讲点云分割——地面分离、聚类分析和物体提取。滤波之后怎么把点云中的不同物体分开是后续识别和跟踪的前提。如果这篇文章对你有帮助欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。「机器人软件开发面试·从入门到精通」连载系列上一篇第148篇 3D激光雷达数据处理——点云结构、格式和处理流程 下一篇预告第150篇 激光雷达点云分割——地面分离、聚类分析和物体提取有任何问题欢迎评论区留言我会尽量回复。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价