Open3D 对点云进行去噪(统计滤波、半径滤波)

在点云处理中,Open3D常见的去噪方法包括:

a. 统计滤波(Statistical Outlier Removal)
基于每个点的邻域点距离分布,移除远离大多数点的“孤立”点,适用场景:

  • 适用于点云数据中存在随机分布的噪声点的情况。
  • 特别适合于具有相对均匀密度的点云数据集。
  • 当你希望保留尽可能多的有效点而仅去除明显偏离的孤立点时非常有用。

b. 半径滤波(Radius Outlier Removal)

移除那些在指定半径范围内邻居数量不足的点,适用场景:

  • 更适合用于点云中包含明确结构或特征的场景,如建筑物、道路等,其中预期大多数点都有紧密相邻的邻居。
  • 当你知道点云的大致密度并且想要去除那些几乎没有邻居的孤立点时特别有效。

这两种方法都是 Open3D 提供的高效点云去噪手段。
在这里插入图片描述

✅ 方法一:统计滤波(Statistical Outlier Removal)

# 统计滤波参数:
# - nb_neighbors: 每个点用于计算距离的邻域点数
# - std_ratio: 标准差倍数,决定离群值的阈值
cl, ind = filtered_pcd.remove_statistical_outlier(nb_neighbors=20,
                                                   std_ratio=2.0)
# 只保留内点(inliers)
filtered_pcd_clean = filtered_pcd.select_by_index(ind)

参数解释:

  • nb_neighbors: 通常设置为 10~50,取决于点云密度。
  • std_ratio: 越大越宽松,越小越严格,常用值是 1.0~2.5。

✅ 方法二:半径滤波(Radius Outlier Removal)

# 半径滤波参数:
# - nb_points: 在给定半径内必须存在的最小点数
# - radius: 邻域搜索半径
cl, ind = filtered_pcd.remove_radius_outlier(nb_points=10, radius=0.05)
# 只保留满足条件的点
filtered_pcd_clean = filtered_pcd.select_by_index(ind)

参数解释:

  • radius: 点周围搜索邻居的距离范围,单位与点云一致(如米、毫米等)。
  • nb_points: 该范围内至少要包含多少点才被认为是有效点。

🔍 可视化去噪结果

你可以将原始点云和去噪后的点云分别显示出来对比效果:

vis = o3d.visualization.Visualizer()
vis.create_window(window_name="Noisy vs Cleaned Point Cloud")

# 设置渲染选项
render_opt = vis.get_render_option()
render_opt.point_size = 2.0
render_opt.background_color = [0.1, 0.1, 0.1]

# 将两个点云加入可视化器(可选不同颜色区分)
filtered_pcd.paint_uniform_color([1, 0, 0])     # 原始点云红色
filtered_pcd_clean.paint_uniform_color([0, 1, 0])  # 去噪后绿色

vis.add_geometry(filtered_pcd)
vis.add_geometry(filtered_pcd_clean)

vis.run()
vis.destroy_window()

📦完整代码

import open3d as o3d
import numpy as np


def StatisticalOutlierRemoval(filtered_pcd):
    """
    统计滤波参数:
    - nb_neighbors: 每个点用于计算距离的邻域点数
    - std_ratio: 标准差倍数,决定离群值的阈值
    """
    cl, ind = filtered_pcd.remove_statistical_outlier(nb_neighbors=10,
                                                      std_ratio=1)
    # 只保留内点(inliers)
    filtered_pcd_clean = filtered_pcd.select_by_index(ind)
    return filtered_pcd_clean

def RadiusOutlierRemoval(filtered_pcd):
    """
    半径滤波参数:
    - nb_points: 在给定半径内必须存在的最小点数
    - radius: 邻域搜索半径
    """
    cl, ind = filtered_pcd.remove_radius_outlier(nb_points=10, radius=10)
    # 只保留满足条件的点
    filtered_pcd_clean = filtered_pcd.select_by_index(ind)
    return filtered_pcd_clean


if __name__ == "__main__":
    # 读取点云数据
    pcd = o3d.io.read_point_cloud("demo.ply")  # 替换为你的点云文件路径
    # 将点云数据转化为numpy数组
    points = np.asarray(pcd.points)
    colors = np.asarray(pcd.colors)  # 获取颜色数据
    # 筛选Z轴小于设定阈值的点及其对应的颜色
    mask = (points[:, 2] > 500) & (points[:, 2] < 3000)
    filtered_points = points[mask]
    filtered_colors = colors[mask]
    # 交换X轴和Y轴的数据
    filtered_points[:, [0, 1]] = filtered_points[:, [1, 0]]
    # 创建新的点云对象并赋值筛选后的点和颜色
    filtered_pcd = o3d.geometry.PointCloud()
    filtered_pcd.points = o3d.utility.Vector3dVector(filtered_points)
    filtered_pcd.colors = o3d.utility.Vector3dVector(filtered_colors)

    # 点云滤波
    print("过滤前:",len(filtered_pcd.points))
    # filtered_pcd_clean = StatisticalOutlierRemoval(filtered_pcd)
    filtered_pcd_clean = RadiusOutlierRemoval(filtered_pcd)
    print("过滤后:",len(filtered_pcd_clean.points))

    # 可视化前的配置
    vis = o3d.visualization.Visualizer()
    vis.create_window()
    # 设置背景颜色,参数为RGB三元组,范围0-1
    opt = vis.get_render_option()
    opt.background_color = [0.1, 0.1, 0.1]  # 深灰色背景
    # 设置点的大小
    opt.point_size = 2.0  # 根据需要调整大小
    
    # 将两个点云加入可视化器(可选不同颜色区分)
    filtered_pcd.paint_uniform_color([1, 0, 0])     # 原始点云红色
    filtered_pcd_clean.paint_uniform_color([0, 1, 0])  # 去噪后绿色
    vis.add_geometry(filtered_pcd)
    vis.add_geometry(filtered_pcd_clean)
    # vis.add_geometry(filtered_pcd)

    # 运行可视化器
    vis.run()
    vis.destroy_window()
过滤前: 203416
过滤后: 89548

在这里插入图片描述

🧠 补充建议

  • 如果点云密度不均匀,可以先对点云进行 下采样(Voxel Downsample) 再去噪。
  • 如果噪点呈现簇状或线状结构,也可以考虑使用 欧式聚类分割(Cluster DBSCAN) 来识别并移除噪声簇。
  • Open3D 的去噪函数默认返回一个布尔掩码(index),可以通过 select_by_index() 提取干净点云。
### 点云概述 点云是指从受声污染的三维点云数据中移除异常值或不规则的数据点,以恢复更精确和平滑的表面表示。这一过程对于后续处理步骤至关重要,比如曲面重建、特征提取以及视觉展示等。 #### 基于分数模型的点云方案 一种高效的方法是采用基于分数建模策略的技术——Score-Based Point Cloud Denoising (SPCD)[^2]。这种方法借助深度学习框架来构建复杂的映射关系,在保持原有几何特性的前提下有效地减少音影响。它通过训练神经网络预测理想状态下的概率密度函数,并以此指导实际观测值向理论最优解逼近的过程来进行优化调整。 #### 统计学基础之上的简单过滤器 另一种常见的手段则是运用简单的统计原理实施初步筛选。例如,可以计算整个集合内的平均位置及其离散程度(即方差),再依据特定距离度量设定阈值范围;超出此界限者则视为潜在的杂音源而予以剔除[^3]。这类方式易于理解和部署,适用于快速预览效果或者作为其他复杂技术前的一个辅助环节。 #### MATLAB环境下的SOR算法应用实例 针对具体编程平台而言,MATLAB提供了一套成熟的库函数支持用户便捷地调用现成模块完成任务。特别是其中名为“Statistical Outlier Removal”的功能包能够自动执行一系列操作:先是评估局部密集情况,接着标记那些偏离正常趋势较远的对象,最后将其排除在外形成净化后的版本供进一步分析使用[^4]。 ```matlab % 加载点云数据 ptCloud = pcread('noisyPointCloud.ply'); % 应用SOR滤波器 maxNN = 50; % 设置最大邻居数 meanK = 10; % 平均考虑最近邻域大小 [outliers, ~] = pcfitplane(ptCloud, maxNN); inliersIndices = ~ismember(1:length(ptCloud.Location), outliers); cleanedPtCloud = select(ptCloud, inliersIndices); % 显示结果对比 figure; subplot(1,2,1); pcshow(ptCloud); title('Original Noisy Data'); subplot(1,2,2); pcshow(cleanedPtCloud); title('After SOR Filtering'); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值