3. 点云统计滤波去噪
任务目标
本案例使用Open3D实现点云统计滤波去噪。给定一份包含离群噪声的原始点云,通过设置邻域点数(nb_neighbors)与标准差倍数(std_ratio),剔除与邻域平均距离偏差过大的点,并对比滤波前后的点云数量与可视化效果。
环境与依赖
- Python 3.8+,安装Open3D:
pip install open3d - 无需额外数据文件,代码使用Open3D内置的
pcd_noise.ply示例点云(含高斯噪声)
完整实现
import open3d as o3d
import numpy as np
# 1. 加载带噪声的点云(Open3D内置示例)
pcd = o3d.data.PCDPointCloud().pcd_path
cloud = o3d.io.read_point_cloud(pcd)
print(f"原始点云点数: {len(cloud.points)}")
# 2. 统计滤波去噪
def statistical_filter(point_cloud, nb_neighbors=20, std_ratio=2.0):
"""统计滤波:计算每个点到邻域的平均距离,剔除超过全局均值+std_ratio*标准差的点"""
cl, ind = point_cloud.remove_statistical_outlier(
nb_neighbors=nb_neighbors, # 邻域点数
std_ratio=std_ratio # 标准差倍数
)
return cl, ind
# 3. 执行滤波(可修改参数观察效果变化)
filtered_cloud, inlier_indices = statistical_filter(cloud, nb_neighbors=20, std_ratio=2.0)
print(f"滤波后点数: {len(filtered_cloud.points)}")
print(f"剔除点数: {len(cloud.points) - len(filtered_cloud.points)}")
# 4. 可视化对比(左:原始,右:滤波后)
cloud.paint_uniform_color([0.8, 0.2, 0.2]) # 原始点云红色
filtered_cloud.paint_uniform_color([0.2, 0.6, 0.2]) # 滤波后绿色
o3d.visualization.draw_geometries([cloud, filtered_cloud])
# 5. 保存结果(可选)
o3d.io.write_point_cloud("filtered_output.ply", filtered_cloud)
运行与验证
- 运行方式:将上述代码保存为
statistical_filter.py,在终端执行python statistical_filter.py。 - 预期输出(基于Open3D内置示例,不同版本点数略有差异):
- 原始点云点数:约 5062
- 滤波后点数:约 4778(具体数值随参数变化)
- 剔除点数:约 284
- 可视化验证:弹出窗口中将显示红色原始点云与绿色滤波后点云。绿色点云中远离主体表面的稀疏离群点应明显减少,主体结构保持完整。
- 参数调优观察:修改
nb_neighbors(如10、50)或std_ratio(如1.0、3.0),观察点数变化——std_ratio越小剔除越多,nb_neighbors越大对局部密度更敏感。
判定标准
- 程序无报错运行,控制台输出滤波前后点数且滤波后点数小于原始点数。
- 可视化窗口中绿色点云比红色点云明显更干净,稀疏离群点被有效去除,且主体几何形状未发生明显形变。
- 调整参数后点数随之变化,说明滤波效果受邻域点数与标准差倍数控制。