3、点云预处理:体素滤波降采样、统计滤波去噪、半径滤波去噪、直通滤波
各位同学,咱们今天聊聊点云预处理。说实话,很多刚入行的朋友拿到ToF点云就直接往上怼配准算法,结果跑出来一堆鬼影。我当年也干过这种傻事——在实验室里对着一个布满噪点的点云图发呆,配准结果歪得离谱。后来才明白,预处理这一步要是没做好,后面全是白费功夫。
点云预处理,说白了就是给原始数据「洗个澡」。ToF传感器采集到的点云,通常有几个毛病:数据量太大、噪声点多、离群点乱飞。咱们今天要讲的四种滤波方法,就是专门治这些毛病的。
3.1 体素滤波降采样——给点云「减肥」
体素滤波,我习惯叫它「点云减肥术」。你想想看,一个ToF传感器扫一帧,动辄几十万个点。这么多点直接拿去配准,计算量大到离谱。体素滤波的思路很简单:把空间切成一个个小立方体(体素),每个立方体里只保留一个代表点。
这个代表点怎么选?通常取体素内所有点的重心,或者直接取中心点。我个人更推荐用重心,因为能保留更多几何信息。我在一个仓储机器人项目里试过,体素边长设成0.02米,点云从30万点直接降到2万点,配准精度几乎没掉。
// C++ PCL 示例
pcl::VoxelGrid<pcl::PointXYZ> voxel_filter;
voxel_filter.setInputCloud(cloud);
voxel_filter.setLeafSize(0.02f, 0.02f, 0.02f); // 体素边长2cm
voxel_filter.filter(*cloud_filtered);
3.2 统计滤波去噪——揪出「孤魂野鬼」
统计滤波,专门对付那些飘在空中的孤立噪点。ToF传感器在边缘或者反光表面容易产生一些「幽灵点」,这些点周围通常没什么邻居。统计滤波的原理就是:对每个点,计算它到k个最近邻的平均距离。如果这个距离太大,说明它是离群点,直接干掉。
为什么会这样?因为有效点云通常聚集在一起,而噪声点往往是孤立的。我记得有一次在户外扫一个金属雕塑,阳光干扰导致一堆飞点。统计滤波一把梭哈,干净多了。
// C++ PCL 示例
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud(cloud);
sor.setMeanK(50); // 考虑50个最近邻
sor.setStddevMulThresh(1.0); // 标准差倍数
sor.filter(*cloud_filtered);
3.3 半径滤波去噪——另一种「查户口」方式
半径滤波和统计滤波有点像,但思路不同。它是在每个点周围画一个固定半径的球,数一数球里有多少个邻居。如果邻居数量少于某个阈值,就认为这个点是离群点。
你想想看,这招特别适合处理那些「扎堆」的噪声。比如ToF传感器在玻璃边缘产生的噪点,它们往往是一小撮一小撮出现的。统计滤波可能把它们当成有效点,但半径滤波一看——周围邻居太少,直接干掉。
// C++ PCL 示例
pcl::RadiusOutlierRemoval<pcl::PointXYZ> ror;
ror.setInputCloud(cloud);
ror.setRadiusSearch(0.05); // 搜索半径5cm
ror.setMinNeighborsInRadius(10); // 至少10个邻居
ror.filter(*cloud_filtered);
3.4 直通滤波——「切蛋糕」一样简单
直通滤波,说白了就是切掉你不需要的部分。比如你只关心地面以上1米到2米范围内的点云,那就设一个z轴范围,把外面的全扔掉。
这招在预处理里特别实用。我记得做AGV小车导航时,天花板上的点云全是干扰,直通滤波一刀切掉z>2.5米的部分,计算量直接减半。而且它不会改变点云的几何结构,只是裁剪范围。
// C++ PCL 示例
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud(cloud);
pass.setFilterFieldName("z"); // 沿z轴裁剪
pass.setFilterLimits(0.5, 2.0); // 保留0.5m到2.0m范围
pass.filter(*cloud_filtered);
3.5 四种滤波的搭配使用
在实际项目中,我很少只用一种滤波。通常的流程是:
- 先直通滤波:把明显不需要的区域切掉,减少后续计算量。
- 再体素滤波:降采样,把点云数量压到可控范围。
- 最后统计滤波或半径滤波:根据噪声类型选一个,或者两个都用。
这个顺序是我踩过坑之后总结出来的。如果你先做统计滤波再做体素滤波,那些稀疏的离群点被体素滤波一平均,反而可能混进有效点里。顺序很重要。
好了,这一节的内容就到这里。预处理这块看似基础,但真到了实战中,参数调优往往是最耗时的环节。别急,多试几次就有感觉了。