3. 点云去噪
任务目标
使用统计滤波(Statistical Outlier Removal)去除点云中的稀疏离群点噪声,调整邻域点数与标准差阈值参数,通过可视化对比和定量指标评估去噪质量。
环境依赖
Python 3.8+,安装 open3d 与 numpy:
pip install open3d numpy
实现代码
以下代码生成含噪声的合成点云(球面点+随机离群点),执行统计滤波,并输出去噪前后的点云文件与质量指标:
import open3d as o3d
import numpy as np
# 1. 生成合成点云:球面点 + 稀疏离群噪声
np.random.seed(42)
theta = np.random.uniform(0, np.pi, 2000)
phi = np.random.uniform(0, 2 * np.pi, 2000)
r = 1.0
sphere = np.stack([
r * np.sin(theta) * np.cos(phi),
r * np.sin(theta) * np.sin(phi),
r * np.cos(theta)
], axis=1)
# 添加少量真实表面噪声(小幅偏移)
surface_noise = np.random.normal(0, 0.01, sphere.shape)
sphere += surface_noise
# 添加离群点(均匀分布在球外区域)
n_outliers = 100
outliers = np.random.uniform(-2, 2, (n_outliers, 3))
cloud_raw = np.vstack([sphere, outliers])
pcd_raw = o3d.geometry.PointCloud()
pcd_raw.points = o3d.utility.Vector3dVector(cloud_raw)
# 2. 统计滤波去噪
pcd_clean, ind = pcd_raw.remove_statistical_outlier(
nb_neighbors=20, # 邻域点数
std_ratio=2.0 # 标准差倍数阈值
)
# 3. 保存结果
o3d.io.write_point_cloud("raw.pcd", pcd_raw)
o3d.io.write_point_cloud("clean.pcd", pcd_clean)
# 4. 定量评估
total = len(cloud_raw)
removed = total - len(pcd_clean)
print(f"原始点数: {total}")
print(f"去除点数: {removed}")
print(f"去除比例: {removed / total:.2%}")
# 已知真实标签(前2000为表面点,后100为离群点)
labels = np.array([1]*2000 + [0]*100) # 1=内点, 0=离群点
pred = np.zeros(total, dtype=int)
pred[ind] = 1 # 保留的点标记为1
tp = np.sum((pred == 1) & (labels == 1))
fp = np.sum((pred == 1) & (labels == 0))
fn = np.sum((pred == 0) & (labels == 1))
precision = tp / (tp + fp) if (tp + fp) > 0 else 0
recall = tp / (tp + fn) if (tp + fn) > 0 else 0
f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0
print(f"精确率: {precision:.3f}")
print(f"召回率: {recall:.3f}")
print(f"F1分数: {f1:.3f}")
运行与可视化验证
- 运行脚本后,当前目录生成
raw.pcd与clean.pcd。 - 执行以下命令可视化对比去噪效果:
python -c "import open3d as o3d; p=o3d.io.read_point_cloud('raw.pcd'); o3d.visualization.draw_geometries([p])"
python -c "import open3d as o3d; p=o3d.io.read_point_cloud('clean.pcd'); o3d.visualization.draw_geometries([p])"
观察原始点云中球体外部存在明显离散点,去噪后这些点被移除,球面结构保持完整。
判定标准
- 控制台输出的去除比例约为 4%~5%(100/2100),F1分数应高于 0.95,表明离群点被有效识别且表面点基本保留。
- 可视化中
clean.pcd的球体表面无明显空洞或变形,外部无残留离群点。
参数调整说明
增大 nb_neighbors 会使滤波更保守(去除更少点);减小 std_ratio 会提高敏感度(去除更多点)。实际应用中可对真实扫描点云先可视化,再根据噪声密度迭代调整这两个参数,以表面细节保留与噪声清除的平衡为准。