前言
- 对坐标轴上的上下限进行约束,选取其中符合范围的点云区域
- 使用场景:去除噪声点,关注特定区域,减小计算量
工作流程
- 假设我们要在 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}}
dmin≤di≤dmax
- 其中 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′={Pi∈P∣dmin≤di≤dmax}
具体示例
- 选择滤波轴:例如选择在
x
轴、y
轴或z
轴上进行过滤。 - 设置上下限:例如,在
z
轴上设定一个范围,如z_min = 0.5
,z_max = 1.5
,表示只保留高度在0.5到1.5之间的点。 - 过滤点云:滤波器会遍历整个点云数据,保留满足条件的点,丢弃超出上下限的点。
代码实现
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])
原始数据点云:
滤波后显示区域: