直通滤波-PassThrough Filter-原理-代码实现

前言

  • 对坐标轴上的上下限进行约束,选取其中符合范围的点云区域
  • 使用场景:去除噪声点,关注特定区域,减小计算量

工作流程

  • 假设我们要在 d d d 轴( d ∈ { x , y , z } d \in \{x, y, z\} d{ x,y,z} )上应用直通滤波
  • 设定该轴的下限为 d min d_{\text{min}} dmin ,上限为 d max d_{\text{max}} dmax,那么点 P i P_i Pi 是否被保留可以用以下公式表示: P i = ( x i , y i , z i ) P_i = (x_i, y_i, z_i) Pi=(xi,yi,zi)
  • 滤波条件为: d min ≤ d i ≤ d max d_{\text{min}} \leq d_i \leq d_{\text{max}} dmindidmax
    • 其中 d i d_i di 是点 P i P_i Pi 在指定轴上的坐标值(即 x i x_i xi y i y_i yi z i z_i zi)。直通滤波的结果是保留满足该条件的点,丢弃其他点。
  • 假设点云的初始集合为 P = { P 1 , P 2 , . . . , P N } \mathcal{P} = \{P_1, P_2, ..., P_N\} P={ P1,P2,...,PN},经过直通滤波后,得到新的点云集合 P ′ \mathcal{P}' P,它由所有满足滤波条件的点构成:
    • P ′ = { P i ∈ P ∣ d min ≤ d i ≤ d max } \mathcal{P}' = \{P_i \in \mathcal{P} \mid d_{\text{min}} \leq d_i \leq d_{\text{max}}\} P={ PiPdmindidmax}

具体示例

  1. 选择滤波轴:例如选择在x轴、y轴或z轴上进行过滤。
  2. 设置上下限:例如,在z轴上设定一个范围,如z_min = 0.5z_max = 1.5,表示只保留高度在0.5到1.5之间的点。
  3. 过滤点云:滤波器会遍历整个点云数据,保留满足条件的点,丢弃超出上下限的点。

代码实现

import open3d as o3d
import numpy as np

def passthrough_filter(point_cloud, axis='z', lower_limit=0.0, upper_limit=1.0):
    """
    对点云数据应用 PassThrough 过滤器,只保留指定范围内的点。

    参数:
        point_cloud (open3d.geometry.PointCloud): 输入点云数据。
        axis (str): 过滤的轴 ('x', 'y' 或 'z')。
        lower_limit (float): 过滤的下限。
        upper_limit (float): 过滤的上限。

    返回值:
        open3d.geometry.PointCloud: 过滤后的点云数据。
    """
    # 将点云数据转换为 numpy 数组
    points = np.asarray(point_cloud.points)
    
    # 根据指定轴进行过滤
    if axis == 'x':
        mask = (points[:, 0] >= lower_limit) & (points[:, 0] <= upper_limit)
    elif axis == 'y':
        mask = (points[:, 1] >= lower_limit) & (points[:, 1] <= upper_limit)
    elif axis == 'z':
        mask = (points[:, 2] >= lower_limit) & (points[:, 2] <= upper_limit)
    else:
        raise ValueError("Axis must be 'x', 'y', or 'z'")

    # 应用过滤器
    filtered_points = points[mask]
    
    # 创建新的点云对象
    filtered_cloud = o3d.geometry.PointCloud()
    filtered_cloud.points = o3d.utility.Vector3dVector(filtered_points)
    
    return filtered_cloud

# 加载点云数据
point_cloud = o3d.io.read_point_cloud("./data/33pod.ply")

# 对点云应用 PassThrough 过滤器
filtered_point_cloud = passthrough_filter(point_cloud, axis='z', lower_limit=10, upper_limit=20)


o3d.visualization.draw_geometries([point_cloud])
o3d.visualization.draw_geometries([filtered_point_cloud])

原始数据点云:
Pasted image 20240921213047
滤波后显示区域:
Pasted image 20240921213103

猜你喜欢

转载自blog.csdn.net/u012901740/article/details/142424881