1.均值滤波算法原理与流程

1.1 算法原理

均值滤波通过邻域内点的坐标平均来平滑噪声,适用于消除高斯噪声。数学表达式为: [ \bar{\mathbf{p}}i = \frac{1}{k}\sum{j=1}^{k} \mathbf{p}_j ] 其中 (\bar{\mathbf{p}}_i) 为滤波后点坐标,(\mathbf{p}_j) 为邻域点坐标,(k) 为邻域点数。

1.2 算法流程

  1. 读取点云数据
  2. 构建KDTree加速邻域搜索
  3. 对每个点执行:
    • 搜索K近邻(含自身)
    • 计算邻域坐标均值
    • 更新当前点坐标
  4. 保存滤波后点云
  5. 可视化并保存输入输出图像

1.3参考文献

[1] Rusu R B. Semantic 3D Object Maps for Everyday Manipulation[M]. Springer, 2010.

2.代码实现

import open3d as o3d
import numpy as np

def mean_filter(pcd, k=20):
    # 构建KDTree
    pcd_tree = o3d.geometry.KDTreeFlann(pcd)
    points = np.asarray(pcd.points)
    filtered_points = np.zeros_like(points)
    
    # 遍历每个点
    for i in range(points.shape[0]):
        [k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[i], k)
        # 计算邻域均值
        neighbors = points[idx, :]
        filtered_points[i] = np.mean(neighbors, axis=0)
    
    # 更新点云
    filtered_pcd = o3d.geometry.PointCloud()
    filtered_pcd.points = o3d.utility.Vector3dVector(filtered_points)
    return filtered_pcd

def save_pcd_as_image(pcd, filename):
    vis = o3d.visualization.Visualizer()
    vis.create_window(visible=False)
    vis.add_geometry(pcd)
    vis.update_geometry(pcd)
    vis.poll_events()
    vis.update_renderer()
    vis.capture_screen_image(filename)
    vis.destroy_window()

# 主程序
if __name__ == "__main__":
    # 读取点云
    pcd = o3d.io.read_point_cloud("input.pcd")
    
    # 执行滤波
    filtered_pcd = mean_filter(pcd, k=20)
    
    # 保存结果
    o3d.io.write_point_cloud("filtered.pcd", filtered_pcd)
    
    # 保存可视化图像
    save_pcd_as_image(pcd, "input.png")
    save_pcd_as_image(filtered_pcd, "output.png")

 3.成果输出

 

原始点云图

统计滤波结果图

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐