PointPillars:数据预处理

在 PointPillars 算法中,将点云划分为点柱(Pillars)是核心步骤之一,用于将稀疏点云数据转换为规则的张量表示,方便后续 2D 卷积操作。以下是点云划分为点柱的具体方法和实现步骤:


1. 点云划分为网格

将 3D 空间划分为规则的网格,形成柱状区域(Pillars)。

操作步骤:
  1. 定义网格范围和分辨率

    • 确定点云的空间范围,例如:
      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
  2. 计算网格索引

    • 对每个点 ( 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=ΔXxXmin,v=ΔYyYmin
    • u , v u, v u,v 分别是点在 X X X Y Y Y 方向上的网格索引。

2. 构建 Pillar 数据结构

每个 Pillar 中包含若干点的特征(点云数据是稀疏的,因此部分 Pillar 可能没有点)。

操作步骤:
  1. 点分组

    • 将所有点根据其网格索引分配到对应的 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)}
  2. 固定点数量

    • 为了适配神经网络,每个 Pillar 中的点数量固定为 N max N_{\text{max}} Nmax
      • 如果点数超过 N max N_{\text{max}} Nmax,随机采样。
      • 如果点数不足 N max N_{\text{max}} Nmax,用零点填充。
  3. 特征提取
    对每个点提取以下特征:

    • ( 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=xxpillar center,Δy=yypillar center
  4. 形成固定维度的张量

    • 对每个 Pillar,构造 N max × D N_{\text{max}} \times D Nmax×D 的特征矩阵,其中 D D D 是特征维度(例如,原始坐标 + 相对坐标 + 强度)。

3. BEV (Bird’s Eye View) 特征图

将所有 Pillar 的特征投影到 BEV 平面,形成伪影像特征图。

操作步骤:
  1. 初始化 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=ΔXXmaxXmin
      • W = Y max − Y min Δ Y W = \frac{Y_{\text{max}} - Y_{\text{min}}}{\Delta Y} W=ΔYYmaxYmin
  2. 填充特征图

    • 对于每个 Pillar,将其特征向量映射到特定网格单元的通道维度中。
  3. 零填充

    • 如果某些网格单元没有对应的 Pillar,用零填充。

代码实现示例

以下是一个简单的 Python 实现框架:

import numpy as np

def 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_size
    pillar_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_size
    pillars = 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

实践优化

  1. GPU 加速:使用 CUDA 或 TensorFlow/PyTorch 操作处理点云。
  2. 稀疏优化:利用稀疏张量库减少计算成本。
  3. 并行化:在点划分和特征提取阶段进行并行处理。

你可能感兴趣的:(激光雷达感知,深度学习,人工智能,神经网络,python,c++)