从稀疏到完整:JS3C-Net如何用场景补全提升点云分割

从稀疏到完整:JS3C-Net如何用场景补全提升点云分割

🚗 自动驾驶入门系列第二篇 | 作者:小探

📅 发布时间:2026年6月10日


前言

上一篇我们介绍了LMSCNet——一个轻量级的3D语义补全网络。今天我们来看另一篇有趣的工作:JS3C-Net(Joint Semantic-Completion and Classification,联合分割补全和分类任务)。

这篇论文的核心思想非常巧妙:通过场景补全任务,让网络学习到"物体应该长什么样"的先验知识,然后用这些知识来提升点云分割的效果


一、问题背景:为什么需要这篇论文?

1.1 单帧LiDAR点云的挑战

想象你用LiDAR扫描一辆车,只能得到车表面的点,车内部是空的。这就是单帧(single sweep)点云的特点:

单帧点云特点:
✓ 只包含物体表面点
✓ 点云非常稀疏(一辆车可能只有几十个点)
✗ 看不到被遮挡的部分
✗ 无法获取完整的3D结构

1.2 现有方法的局限

方法类型 问题
纯分割方法 只关注可见点,忽略上下文
纯补全方法 只预测占用,不区分语义
体素化方法 丢失点级精度

1.3 JS3C-Net的核心洞察

"分割"和"补全"是互补的任务!

  • 分割需要知道"这是什么"
  • 补全需要知道"这里应该有什么"

通过联合学习,网络可以学到更丰富的3D形状先验。


二、核心知识点:理解JS3C-Net的关键概念

2.1 什么是上下文形状先验(Contextual Shape Priors)?

形状先验:网络学习到的"物体应该长什么样"的知识。

例子:学习"车"的形状先验
- 车通常是长方体形状
- 车轮在底部四个角
- 车窗在上部
- 即使只看到车的一部分,也能推断出完整形状

2.2 点级特征 vs 体素级特征

JS3C-Net同时处理两种特征:

点级特征(Point-level):
├── 保留精确的点位置
├── 适合精细分割
└── 但缺乏上下文信息

体素级特征(Voxel-level):
├── 提供3D结构信息
├── 适合场景补全
└── 但损失点级精度

2.3 稀疏卷积(Sparse Convolution)

传统3D卷积在空区域也做计算,浪费算力。稀疏卷积只在有点的区域计算:

传统卷积:O(N³) 计算量
稀疏卷积:O(K) 计算量,K << N³

┌─────────────────┐
│ ■ ■ ■ ■ ■ ■ ■ ■ │  ■ = 有点(需要计算)
│ ■ □ □ □ □ □ □ ■ │  □ = 空(跳过计算)
│ ■ □ □ □ □ □ □ ■ │
│ ■ □ □ □ □ □ □ ■ │
│ ■ □ □ □ □ □ □ ■ │
│ ■ □ □ □ □ □ □ ■ │
│ ■ □ □ □ □ □ □ ■ │
│ ■ ■ ■ ■ ■ ■ ■ ■ │
└─────────────────┘

三、JS3C-Net架构详解

3.1 整体架构

输入:单帧LiDAR点云 [N, 4] (x, y, z, intensity)
        ↓
    ┌───────────────────────────────────────────┐
    │           Sparse UNet 编码器               │
    │  ┌─────────────────────────────────────┐  │
    │  │  稀疏3D卷积层                       │  │
    │  │  (3×3×3 kernel, stride=2)           │  │
    │  └─────────────────────────────────────┘  │
    │              ↓                            │
    │  ┌─────────────────────────────────────┐  │
    │  │  稀疏残差块                         │  │
    │  │  (1×1×1 → 3×3×3 → 1×1×1)          │  │
    │  └─────────────────────────────────────┘  │
    └───────────────────────────────────────────┘
                    ↓
    ┌───────────────┬───────────────┐
    │   点级分支     │   体素级分支   │
    │  (Point Branch)│ (Voxel Branch)│
    └───────┬───────┴───────┬───────┘
            ↓               ↓
    ┌───────────────┐ ┌───────────────┐
    │  点云分割      │ │  场景补全      │
    │  [N, 20]      │ │  [H,W,D,20]   │
    └───────────────┘ └───────────────┘
            ↓               ↓
            └───────┬───────┘
                    ↓
            联合优化损失

3.2 点级分支(Point Branch)

class PointBranch(nn.Module):
    def __init__(self):
        # MLP层
        self.mlp = nn.Sequential(
            nn.Linear(32, 64),
            nn.BatchNorm1d(64),
            nn.ReLU(),
            nn.Linear(64, 128),
            nn.BatchNorm1d(128),
            nn.ReLU()
        )
        # 分类头
        self.classifier = nn.Linear(128, num_classes)

    def forward(self, point_features, voxel_features):
        # 从体素特征中采样到点
        sampled_features = trilinear_interpolation(
            voxel_features, point_coords
        )
        # 融合点级和体素级特征
        fused = torch.cat([point_features, sampled_features], dim=-1)
        # MLP处理
        output = self.mlp(fused)
        # 分类
        seg_pred = self.classifier(output)
        return seg_pred

3.3 体素级分支(Voxel Branch)

class VoxelBranch(nn.Module):
    def __init__(self):
        # 解码器
        self.decoder = nn.Sequential(
            SparseConv3d(128, 64, 3, stride=1),
            SparseConv3d(64, 32, 3, stride=1),
            SparseConv3d(32, num_classes, 1, stride=1)
        )

    def forward(self, sparse_features):
        # 上采样到原始分辨率
        upsampled = sparse_to_dense(sparse_features)
        # 预测占用和语义
        occ_pred = self.decoder(upsampled)
        return occ_pred

3.4 双线性插值聚合(Bilinear Interpolation Aggregation)

这是JS3C-Net的关键创新之一:

def trilinear_interpolation(voxel_features, point_coords):
    """
    将体素特征插值到点位置

    Args:
        voxel_features: [B, C, H, W, D] 体素特征
        point_coords: [N, 3] 点坐标 (归一化到[0,1])

    Returns:
        point_features: [N, C] 点特征
    """
    # 找到每个点周围的8个角点
    corners = get_8_corners(point_coords)

    # 计算插值权重
    weights = compute_bilinear_weights(point_coords, corners)

    # 加权求和
    point_features = sum(
        voxel_features[corner] * weight
        for corner, weight in zip(corners, weights)
    )

    return point_features

四、数据增强:Complete-and-Mask

4.1 传统数据增强的问题

传统增强方法:
- 随机旋转:改变视角,但不改变点云密度
- 随机缩放:改变大小,但不改变稀疏性
- 随机平移:改变位置,但不增加新点

问题:无法模拟更密集的点云

4.2 Complete-and-Mask 增强

JS3C-Net提出了一种新的数据增强方法:

Step 1: 补全(Complete)
├── 用场景补全网络预测完整的3D占用
├── 在占用区域采样新的点
└── 得到更密集的点云

Step 2: 遮挡(Mask)
├── 随机遮挡部分区域
├── 模拟遮挡情况
└── 训练网络预测被遮挡的部分

效果:增加训练数据的多样性,提升泛化能力

五、损失函数设计

5.1 多任务损失

def compute_loss(pred_seg, pred_occ, gt_seg, gt_occ):
    """
    联合优化分割和补全任务
    """
    # 分割损失:加权交叉熵 + Lovász损失
    seg_loss = weighted_cross_entropy(pred_seg, gt_seg) + \
               lovasz_softmax(pred_seg, gt_seg)

    # 补全损失:加权交叉熵
    occ_loss = weighted_cross_entropy(pred_occ, gt_occ)

    # 总损失
    total_loss = seg_loss + 0.5 * occ_loss

    return total_loss

5.2 Lovász损失

为什么需要Lovász损失?

问题:IoU不可微,无法直接优化
解决:Lovász扩展,将IoU转化为可微损失

Lovász损失优势:
✓ 直接优化IoU指标
✓ 对类别不平衡更鲁棒
✓ 提升小物体的分割效果

六、实验结果分析

6.1 SemanticKITTI数据集性能

方法 分割mIoU 补全mIoU 速度
Tang et al. 52.2 - 90ms
MinkowskiNet 63.0 - 70ms
JS3C-Net 69.7 10.6 70ms

6.2 消融实验

配置 分割mIoU 提升
基线(仅分割) 65.4 -
+ 补全任务 67.8 +2.4
+ 双分支融合 68.9 +1.1
+ Complete-and-Mask 69.7 +0.8

关键发现

  1. 补全任务提升分割:+2.4% mIoU
  2. 双分支融合:+1.1% mIoU
  3. 数据增强:+0.8% mIoU

6.3 可视化结果

输入点云          预测分割          真实标签
    ●               ●(车)            ●(车)
   ●●●             ●●●(车)          ●●●(车)
  ●●●●●           ●●●●●(车)        ●●●●●(车)
    ●               ●(路)            ●(路)

七、代码实现要点

7.1 稀疏卷积实现

import torch
import torch.nn as nn

class SparseConv3d(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1):
        super().__init__()
        self.conv = nn.Conv3d(
            in_channels, out_channels,
            kernel_size, stride=stride,
            padding=kernel_size//2
        )
        self.bn = nn.BatchNorm3d(out_channels)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x, coords):
        # 只在有点的位置计算
        dense = sparse_to_dense(x, coords)
        out = self.conv(dense)
        out = self.bn(out)
        out = self.relu(out)
        return dense_to_sparse(out, coords)

7.2 点级-体素级特征融合

def fuse_features(point_features, voxel_features, point_coords):
    """
    融合点级和体素级特征
    """
    # 体素特征插值到点位置
    voxel_at_points = trilinear_interpolation(
        voxel_features, point_coords
    )

    # 拼接特征
    fused = torch.cat([point_features, voxel_at_points], dim=-1)

    # MLP融合
    fused = self.fusion_mlp(fused)

    return fused

7.3 Complete-and-Mask增强

def complete_and_mask(point_cloud, occupancy_grid):
    """
    Complete-and-Mask数据增强
    """
    # Step 1: 从占用网格采样新点
    completed_points = sample_from_occupancy(occupancy_grid)

    # Step 2: 合并原始点云和补全点云
    augmented = torch.cat([point_cloud, completed_points], dim=0)

    # Step 3: 随机遮挡
    mask = random_mask(augmented.shape[0], ratio=0.2)
    augmented = augmented[mask]

    return augmented

八、论文的核心启示

8.1 技术启示

启示 说明
任务互补 分割和补全可以互相促进
多尺度特征 点级+体素级特征更全面
数据增强 Complete-and-Mask有效提升泛化
稀疏卷积 大幅提升计算效率

8.2 工程启示

  1. 联合训练更有效:多任务学习可以学到更丰富的特征
  2. 数据增强很重要:好的增强方法可以显著提升性能
  3. 稀疏卷积是关键:3D任务必须考虑计算效率

8.3 研究启示

  1. 任务设计:选择互补的任务进行联合学习
  2. 特征融合:不同粒度的特征可以互补
  3. 评估指标:同时关注分割和补全性能

九、与LMSCNet的对比

方面 LMSCNet JS3C-Net
任务 仅场景补全 分割+补全
输入 体素化点云 原始点云
特征 体素级 点级+体素级
数据增强 标准增强 Complete-and-Mask
性能 15.3% mIoU 69.7% mIoU
速度 较慢 70ms

十、关键概念速查表

概念 定义 重要性
上下文形状先验 网络学习到的物体形状知识 ⭐⭐⭐⭐⭐
点级特征 保留点位置的特征 ⭐⭐⭐⭐
体素级特征 3D网格结构的特征 ⭐⭐⭐⭐
稀疏卷积 只在有点区域计算的卷积 ⭐⭐⭐⭐⭐
Complete-and-Mask 补全+遮挡的数据增强 ⭐⭐⭐⭐
Lovász损失 可微的IoU损失 ⭐⭐⭐

十一、总结与延伸

11.1 JS3C-Net的贡献

贡献 说明
联合学习框架 分割+补全互相促进
双分支架构 点级+体素级特征融合
Complete-and-Mask 新的数据增强方法
稀疏卷积优化 高效的3D特征提取

11.2 局限性

  1. 仅单帧:未利用时序信息
  2. 计算量:仍然较大(70ms/帧)
  3. 内存占用:稀疏卷积需要大量内存

11.3 后续研究方向

  1. 时序融合:利用多帧点云
  2. 更高效的架构:如MinkowskiNet
  3. 端到端训练:减少中间步骤
  4. 多模态融合:结合相机图像

十二、参考文献

  1. JS3C-Net: Sparse Single Sweep LiDAR Point Cloud Segmentation via Learning Contextual Shape Priors from Scene Completion (AAAI 2021)
  2. MinkowskiNet: 4D Spatio-Temporal ConvNets (CVPR 2020)
  3. SparseConv: 3D Sparse Convolutional Neural Networks (ICLR 2019)
  4. Lovász-Softmax: The Lovász-Softmax Loss (CVPR 2018)

下期预告

下一篇我们将介绍TPVFormer——一种基于三视角(Tri-Perspective View)的视觉中心3D占用感知方法,它如何用相机图像替代LiDAR实现3D理解?

关注我们,持续获取自动驾驶3D感知技术干货!

往期回顾

posted @ 2026-06-10 11:41  探物AI  阅读(24)  评论(0)    收藏  举报