石家庄网站建设推广公司电话百度客服人工
在 PointPillars 算法中,将点云划分为点柱(Pillars)是核心步骤之一,用于将稀疏点云数据转换为规则的张量表示,方便后续 2D 卷积操作。以下是点云划分为点柱的具体方法和实现步骤:
1. 点云划分为网格
将 3D 空间划分为规则的网格,形成柱状区域(Pillars)。
操作步骤:
-
定义网格范围和分辨率:
- 确定点云的空间范围,例如:
X min , X max , Y min , Y max , Z min , Z max X_{\text{min}}, X_{\text{max}}, Y_{\text{min}}, Y_{\text{max}}, Z_{\text{min}}, Z_{\text{max}} Xmin,Xmax,Ymin,Ymax,Zmin,Zmax - 设置网格分辨率(Pillar 尺寸):
Δ X , Δ Y \Delta X, \Delta Y ΔX,ΔY
例如,每个 Pillar 的大小为 0.16 × 0.16 m 0.16 \times 0.16 \, \text{m} 0.16×0.16m。
- 确定点云的空间范围,例如:
-
计算网格索引:
- 对每个点 ( x , y , z ) (x, y, z) (x,y,z),计算其在网格中的索引:
u = ⌊ x − X min Δ X ⌋ , v = ⌊ y − Y min Δ Y ⌋ u = \lfloor \frac{x - X_{\text{min}}}{\Delta X} \rfloor, \quad v = \lfloor \frac{y - Y_{\text{min}}}{\Delta Y} \rfloor u=⌊ΔXx−Xmin⌋,v=⌊ΔYy−Ymin⌋ - u , v u, v u,v 分别是点在 X X X 和 Y Y Y 方向上的网格索引。
- 对每个点 ( x , y , z ) (x, y, z) (x,y,z),计算其在网格中的索引:
2. 构建 Pillar 数据结构
每个 Pillar 中包含若干点的特征(点云数据是稀疏的,因此部分 Pillar 可能没有点)。
操作步骤:
-
点分组:
- 将所有点根据其网格索引分配到对应的 Pillar 中。
- 例如,第 ( u , v ) (u, v) (u,v) 个 Pillar 包含所有满足条件的点:
P pillar ( u , v ) = { ( x , y , z , i ) ∣ 点的索引为 ( u , v ) } P_{\text{pillar}}(u, v) = \{ (x, y, z, i) \mid \text{点的索引为 } (u, v) \} Ppillar(u,v)={(x,y,z,i)∣点的索引为 (u,v)}
-
固定点数量:
- 为了适配神经网络,每个 Pillar 中的点数量固定为 N max N_{\text{max}} Nmax:
- 如果点数超过 N max N_{\text{max}} Nmax,随机采样。
- 如果点数不足 N max N_{\text{max}} Nmax,用零点填充。
- 为了适配神经网络,每个 Pillar 中的点数量固定为 N max N_{\text{max}} Nmax:
-
特征提取:
对每个点提取以下特征:- ( x , y , z , i ) (x, y, z, i) (x,y,z,i):点的原始坐标和反射强度。
- 相对坐标(相对于 Pillar 中心的偏移量):
Δ x = x − x pillar center , Δ y = y − y pillar center \Delta x = x - x_{\text{pillar center}}, \quad \Delta y = y - y_{\text{pillar center}} Δx=x−xpillar center,Δy=y−ypillar center
-
形成固定维度的张量:
- 对每个 Pillar,构造 N max × D N_{\text{max}} \times D Nmax×D 的特征矩阵,其中 D D D 是特征维度(例如,原始坐标 + 相对坐标 + 强度)。
3. BEV (Bird’s Eye View) 特征图
将所有 Pillar 的特征投影到 BEV 平面,形成伪影像特征图。
操作步骤:
-
初始化 BEV 特征图:
- 创建一个固定大小的张量 ( H , W , C ) (H, W, C) (H,W,C),对应网格的高度、宽度和通道数。
- H = X max − X min Δ X H = \frac{X_{\text{max}} - X_{\text{min}}}{\Delta X} H=ΔXXmax−Xmin
- W = Y max − Y min Δ Y W = \frac{Y_{\text{max}} - Y_{\text{min}}}{\Delta Y} W=ΔYYmax−Ymin
- 创建一个固定大小的张量 ( H , W , C ) (H, W, C) (H,W,C),对应网格的高度、宽度和通道数。
-
填充特征图:
- 对于每个 Pillar,将其特征向量映射到特定网格单元的通道维度中。
-
零填充:
- 如果某些网格单元没有对应的 Pillar,用零填充。
代码实现示例
以下是一个简单的 Python 实现框架:
import numpy as npdef create_pillars(point_cloud, grid_size, pillar_size, max_points_per_pillar):"""将点云划分为点柱 (Pillars) 并提取特征。Args:point_cloud: (N, 4) 点云数据,包含 (x, y, z, intensity)grid_size: [x_min, x_max, y_min, y_max]pillar_size: [pillar_x_size, pillar_y_size]max_points_per_pillar: 每个 Pillar 的最大点数Returns:pillars: (num_pillars, max_points_per_pillar, feature_dim)"""x_min, x_max, y_min, y_max = grid_sizepillar_x_size, pillar_y_size = pillar_size# 筛选点云范围内的点mask = (point_cloud[:, 0] >= x_min) & (point_cloud[:, 0] < x_max) & \(point_cloud[:, 1] >= y_min) & (point_cloud[:, 1] < y_max)points = point_cloud[mask]# 计算网格索引x_indices = np.floor((points[:, 0] - x_min) / pillar_x_size).astype(int)y_indices = np.floor((points[:, 1] - y_min) / pillar_y_size).astype(int)# 按索引分组点num_pillars = (x_max - x_min) // pillar_x_size * (y_max - y_min) // pillar_y_sizepillars = np.zeros((num_pillars, max_points_per_pillar, 7)) # [x, y, z, intensity, delta_x, delta_y, delta_z]for i, (x_idx, y_idx) in enumerate(zip(x_indices, y_indices)):pillar_idx = x_idx * y_max + y_idx # Pillar 的一维索引if len(pillars[pillar_idx]) < max_points_per_pillar:delta_x = points[i, 0] - (x_idx * pillar_x_size + pillar_x_size / 2)delta_y = points[i, 1] - (y_idx * pillar_y_size + pillar_y_size / 2)pillars[pillar_idx].append([*points[i, :4], delta_x, delta_y, points[i, 2]])return pillars
实践优化
- GPU 加速:使用 CUDA 或 TensorFlow/PyTorch 操作处理点云。
- 稀疏优化:利用稀疏张量库减少计算成本。
- 并行化:在点划分和特征提取阶段进行并行处理。