4. 深度相机点云预处理

任务目标

对深度相机(如RealSense、Kinect等)获取的原始点云执行三步预处理:直通滤波(裁剪感兴趣区域)、体素降采样(稀疏化)、统计离群点去除(平滑去噪)。输出为可直接用于后续配准或识别的干净点云。

环境依赖

Python 3.8+,安装Open3D(推荐0.17+):

pip install open3d numpy

关键完整代码

import open3d as o3d
import numpy as np

def preprocess_pointcloud(input_path, output_path=None):
    """
    对深度相机点云执行:直通滤波 → 体素降采样 → 统计离群点去除
    Args:
        input_path: 输入点云文件路径(.ply/.pcd)
        output_path: 输出路径,None则返回处理结果不保存
    Returns:
        o3d.geometry.PointCloud: 预处理后的点云
    """
    # 1. 读取原始点云
    pcd = o3d.io.read_point_cloud(input_path)
    if pcd.is_empty():
        raise ValueError(f"点云为空或读取失败: {input_path}")
    print(f"原始点云点数: {len(pcd.points)}")

    # 2. 直通滤波:裁剪工作空间(单位:米,按需调整)
    bbox = o3d.geometry.AxisAlignedBoundingBox(
        min_bound=np.array([-0.5, -0.5, 0.0]),   # x,y,z最小值
        max_bound=np.array([0.5, 0.5, 0.8])      # x,y,z最大值
    )
    pcd_cropped = pcd.crop(bbox)
    print(f"直通滤波后点数: {len(pcd_cropped.points)}")

    # 3. 体素降采样:体素边长5mm(稀疏化并均匀化密度)
    voxel_size = 0.005
    pcd_down = pcd_cropped.voxel_down_sample(voxel_size)
    print(f"降采样后点数: {len(pcd_down.points)}")

    # 4. 统计离群点去除:邻域点数20,标准差阈值1.0
    pcd_clean, ind = pcd_down.remove_statistical_outlier(
        nb_neighbors=20, std_ratio=1.0
    )
    print(f"去离群点后点数: {len(pcd_clean.points)}")

    # 5. 保存或返回
    if output_path:
        o3d.io.write_point_cloud(output_path, pcd_clean)
        print(f"已保存至: {output_path}")
    return pcd_clean

if __name__ == "__main__":
    # 使用示例:替换为实际深度相机导出的点云文件
    result = preprocess_pointcloud("raw_scene.ply", "clean_scene.ply")
    # 可视化验证(取消注释以查看)
    # o3d.visualization.draw_geometries([result])

运行与验证

  1. 准备输入:将深度相机(RealSense D435等)采集的帧保存为raw_scene.ply,或使用Open3D自带的示例点云测试:
python -c "import open3d as o3d; o3d.data.DemoCropPointCloud().point_cloud_path"
  1. 执行预处理:将上述代码保存为preprocess.py,运行:
python preprocess.py
  1. 通过条件:
    - 控制台输出四个点数依次递减(原始→裁剪→降采样→去噪),且最终点数不为0;
    - 生成clean_scene.ply文件,用o3d.visualization.draw_geometries打开后,点云边界清晰、无明显漂浮噪声点、密度均匀;
    - 若原始点云含超出工作空间的点(如天花板、地面远处),直通滤波后这些点应被移除。

参数调整说明

参数位置推荐范围调整依据
bbox边界直通滤波根据机器人工作空间设定过大保留无关点,过小裁掉目标物体
voxel_size降采样0.003~0.01m值越大点越稀疏,需保留足够几何特征
nb_neighbors去离群点10~50邻域点数越多,对密度变化越不敏感
std_ratio去离群点0.5~2.0越小去除越多,过大则保留噪声

常见问题

  • 输入点云单位:RealSense默认单位米,若数据单位是毫米,需先将坐标除以1000再滤波;
  • 点数过少:若降采样后点数不足1000,说明体素尺寸过大或原始点云太稀疏,应减小voxel_size;
  • 离群点未去除干净:降低std_ratio至0.5,或增大nb_neighbors至30;
  • 实时性要求:若需在线处理,建议将voxel_size调至0.008以上,并限制bbox范围以降低计算量。