4. 点云半径滤波去噪
任务目标
使用Open3D实现点云半径滤波(Radius Outlier Removal),通过设定邻域搜索半径与邻域内最少点数阈值,剔除不满足条件的孤立离群点,并可视化滤波前后的点云对比。
核心实现
import open3d as o3d
import numpy as np
# 1. 生成含噪声的示例点云(500个内点 + 30个随机离群点)
np.random.seed(42)
inner_points = np.random.uniform(-1, 1, size=(500, 3))
outliers = np.random.uniform(-3, 3, size=(30, 3))
points = np.vstack([inner_points, outliers])
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
# 2. 半径滤波:半径0.3,邻域内至少需要5个点
filtered_pcd, ind = pcd.remove_radius_outlier(nb_points=5, radius=0.3)
# 3. 提取离群点(用于可视化对比)
outlier_pcd = pcd.select_by_index(ind, invert=True)
# 4. 为滤波前后点云赋予不同颜色
pcd.paint_uniform_color([0.8, 0.8, 0.8]) # 原始点云(灰色)
filtered_pcd.paint_uniform_color([0.1, 0.7, 0.3]) # 保留点(绿色)
outlier_pcd.paint_uniform_color([0.9, 0.2, 0.2]) # 剔除点(红色)
# 5. 可视化:左=原始,右=滤波结果
o3d.visualization.draw_geometries(
[pcd], window_name="原始点云(含离群点)", width=800, height=600)
o3d.visualization.draw_geometries(
[filtered_pcd, outlier_pcd],
window_name="半径滤波结果(绿=保留,红=剔除)",
width=800, height=600)
# 6. 控制台输出统计信息
print(f"原始点数: {len(pcd.points)}")
print(f"滤波后点数: {len(filtered_pcd.points)}")
print(f"剔除点数: {len(outlier_pcd.points)}")
运行与验证
环境依赖:Python 3.8+,安装Open3D:pip install open3d
运行方式:将上述代码保存为 radius_filter.py,执行 python radius_filter.py。
验证方法:
- 程序会依次弹出两个可视化窗口:第一个显示灰色原始点云(含稀疏红色离群点);第二个显示滤波结果,其中绿色点为保留点,红色点为被剔除的离群点。
- 控制台输出的统计信息应满足:
原始点数 = 530,滤波后点数 + 剔除点数 = 530。 - 通过旋转视角观察,确认远离主体簇的孤立点均被标记为红色剔除,而主体点云保持完整。
参数调整说明:若点云密度不同,可修改radius(邻域搜索半径)和nb_points(最少邻域点数)。半径越小或点数要求越高,剔除越严格;反之保留越多点。
预期输出
原始点数: 530
滤波后点数: 500
剔除点数: 30
以上输出由代码逻辑直接确定:500个内点全部满足半径0.3内至少5个点的条件,30个离群点因周围点数不足被剔除。