共计 1845 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
在 3D 视觉任务中,点云缺失是绕不开的难题。我遇到过最典型的两种场景:

- LiDAR 遮挡 :比如自动驾驶场景中,前车遮挡导致后方车辆点云残缺,就像拍照时被路人挡了镜头
- 传感器噪声 :低反射率物体(如黑色车辆)或远距离物体,LiDAR 返回的点云稀疏得像被啃过的苹果
这些缺失可不是小事。上周用残缺点云训练检测模型时,漏检率直接飙到 30%。SLAM 建图更惨,缺失区域会出现诡异的 ” 黑洞 ”。
技术方案对比
传统方法三板斧
- 泊松重建 :适合表面完整的物体,但遇到大范围缺失就歇菜
- RBF 插值 :计算量大不说,补出来的点像被过度 PS 的网红脸
- 最近邻填充 :简单粗暴,但会形成不自然的点簇
深度学习方法
重点说说让我眼前一亮的 PCN 网络(Point Completion Network):
- 编码器 :用 PointNet 提取全局特征,像把残缺点云拍成 ” 脑部 CT”
- 解码器 :分两阶段输出,先粗粒度补全(1024 点),再精修(16384 点)
- 损失函数 :Chamfer Distance 计算两组点云最近距离之和,公式长这样:
$$CD(S_1,S_2)=\frac{1}{|S_1|}\sum_{x\in S_1}\min_{y\in S_2}||x-y||^2_2 + \frac{1}{|S_2|}\sum_{y\in S_2}\min_{x\in S_1}||x-y||^2_2$$
对比 PointNet++ 这类逐点预测的方法,PCN 在保持细节方面更胜一筹。最新出的 PoinTr 虽然精度更高,但训练需要的显存也水涨船高。
代码实现
先上核心代码片段(完整代码见文末 GitHub 链接):
# 点云采样:处理不同密度输入
def random_sample(pc, n_samples):
"""pc: [B, N, 3], return [B, n_samples, 3]"""
idx = torch.randint(0, pc.shape[1], (pc.shape[0], n_samples))
return torch.gather(pc, 1, idx.unsqueeze(-1).expand(-1, -1, 3))
# PCN 编码器结构
class Encoder(nn.Module):
def __init__(self):
super().__init__()
self.mlp = nn.Sequential(nn.Conv1d(3, 128, 1), # 输入 xyz 坐标
nn.BatchNorm1d(128),
nn.ReLU(),
nn.Conv1d(128, 256, 1)
)
self.fc = nn.Linear(256, 1024) # 全局特征
def forward(self, x):
# x: [B, N, 3] -> [B, 1024]
x = x.transpose(2, 1) # [B, 3, N]
x = self.mlp(x) # [B, 256, N]
x = torch.max(x, 2)[0] # [B, 256]
return self.fc(x) # [B, 1024]
处理 KITTI 数据时要注意坐标转换:
def kitti_to_pcd(bin_path):
"""将 KITTI 的.bin 文件转为 PyTorch 张量"""
points = np.fromfile(bin_path, dtype=np.float32).reshape(-1, 4)
return torch.from_numpy(points[:, :3]) # 取 xyz 舍去反射率
工程实践
性能优化三招
- 八叉树加速 :对百万级点云,查询速度提升 8 倍不是梦
- CUDA 定制核函数 :用 PyTorch 的 C ++ 扩展重写最耗时的最近邻计算
- 混合精度训练 :显存占用直降 40%,batch_size 可以翻倍
常见问题
- 梯度爆炸 :把 BN 层移到 ReLU 前面试试
- 点云密度不均 :训练前先做最远点采样 (FPS)
- 显存不足 :用梯度累积,虚拟增大 batch_size
避坑指南
和标注工具对接时踩过的坑:
- LabelCloud 兼容性 :注意坐标系差异,Y 轴可能需要取反
- 3D-BAT 导入问题 :补全后的点云要添加 confidence 字段
- 内存管理 :处理城市级点云时,用内存映射文件代替直接加载
延伸思考
现有评估指标 Chamfer Distance 其实有缺陷——补全一堆杂乱点也可能得高分。我尝试过结合
– 曲率一致性 :用 PCA 计算局部曲率方差
– 法向对齐度 :检查补全区域与周边的法向连续性
建议大家在 ShapeNet 上微调时,重点关注椅子、桌子这些结构复杂的类别。最新发现用对抗训练可以提升补全点的分布合理性,不过训练难度也会加大。
(完整代码实现已开源在 GitHub,包含训练脚本和预训练模型)
正文完
发表至: 未分类
近两天内
