2. 点云预处理
任务目标
本案例使用PCL(Point Cloud Library)对激光雷达点云执行统计滤波(StatisticalOutlierRemoval),去除稀疏离群点,提升点云数据质量。输入为包含噪声的原始点云,输出为滤波后的干净点云,并保存为PCD文件以便后续处理。
环境依赖
- Ubuntu 20.04+ / Windows 10+
- PCL 1.10+(含pcl_io、pcl_filters模块)
- CMake 3.10+
- C++11及以上编译器
关键完整代码
// statistical_filter.cpp
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <iostream>
int main(int argc, char** argv) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " input.pcd output.pcd" << std::endl;
return -1;
}
// 加载点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) == -1) {
std::cerr << "Failed to load " << argv[1] << std::endl;
return -1;
}
std::cout << "Input points: " << cloud->size() << std::endl;
// 统计滤波:每个点的邻域点数 < 50 或距离均值偏差 > 1.0 倍标准差则剔除
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud(cloud);
sor.setMeanK(50); // 查询邻域点数
sor.setStddevMulThresh(1.0); // 标准差倍数阈值
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
sor.filter(*cloud_filtered);
std::cout << "Filtered points: " << cloud_filtered->size() << std::endl;
// 保存结果
pcl::io::savePCDFileBinary(argv[2], *cloud_filtered);
std::cout << "Saved to " << argv[2] << std::endl;
return 0;
}
CMake配置
cmake_minimum_required(VERSION 3.10)
project(statistical_filter)
find_package(PCL 1.10 REQUIRED COMPONENTS io filters)
add_executable(statistical_filter statistical_filter.cpp)
target_link_libraries(statistical_filter ${PCL_LIBRARIES})
add_definitions(${PCL_DEFINITIONS})
编译与运行
# 编译
mkdir build && cd build
cmake ..
make
# 运行(需准备含噪声的输入PCD文件)
./statistical_filter ../noisy_cloud.pcd ../filtered_cloud.pcd
验证方法
- 点数对比:程序输出中
Filtered points应明显小于Input points,表明离群点被剔除。 - 可视化检查:使用PCL可视化工具或CloudCompare打开
filtered_cloud.pcd,观察点云主体结构完整,稀疏飞点消失。 - 参数调优:若主体点云被误删,增大
setMeanK或setStddevMulThresh;若噪声残留,则减小阈值。
预期输出示例
Input points: 128934
Filtered points: 121567
Saved to ../filtered_cloud.pcd
以上输出仅为逻辑推演示例,实际数值取决于输入点云噪声分布。
常见问题
- 加载失败:确认PCD文件路径正确且文件为ASCII或二进制格式。
- 滤波过度:点云主体被大量删除时,应增大
setMeanK(如100)或setStddevMulThresh(如2.0)。 - 滤波不足:仍有明显离群点时,减小
setStddevMulThresh至0.5或降低setMeanK。