资讯动态

点云实例分割新思路:基于点级别包围盒回归与位置聚类

发布时间:2026/10/13 0:34:31 来源:尧图企业网站定制
1. 从二维检测到三维实例分割这个项目到底在解决什么问题点云实例分割这个方向如果你做过三维视觉相关的项目大概率被它折磨过。激光雷达扫出来的一帧数据动辄十几万个点散乱、无序、密度不均没有规则的网格结构你没法像处理图像那样直接套卷积。而实例分割的目标比语义分割更苛刻——不光要知道每个点属于车还是人还得区分出这是第一辆车那是第二辆车。2019年之前这个领域的主流做法大概分两条路。一条是基于候选框的两阶段方案先做3D目标检测生成一堆候选框再在框内做点级别的掩码预测典型代表如GSPN之类的框架。另一条是基于点聚类的方法先做语义分割再用均值漂移或者DBSCAN把同类的点聚成实例。这两条路我都实际跑过问题非常明显两阶段方案严重依赖检测框的质量框不准后面全废聚类方案则对密度变化和超参数极度敏感同一个场景换个参数结果天差地别。这个项目的核心思路很有意思——它把实例分割问题转化成了点级别的边界框回归问题。具体来说网络对每个点预测一个它所属实例的包围盒然后通过一种叫做位置聚类的后处理把预测出相似包围盒的点归为同一个实例。这个思路的巧妙之处在于它绕开了传统方案中先检测再分割的串行依赖也绕开了聚类方法对距离度量的敏感直接用包围盒参数作为点的身份指纹。我第一次读到这个思路的时候脑子里蹦出来的类比是想象一群人在一个大广场上每个人手里举着一个牌子牌子上写着他认为自己所处团队的活动范围坐标。如果两个人属于同一个团队他们写的范围应该差不多。我们只需要把写相似范围的人归到一起就行了。这个类比虽然粗糙但核心逻辑就是这样——用回归出来的几何参数代替传统的特征嵌入来做聚类。这个方案适合谁参考如果你正在做自动驾驶感知、机器人室内导航、工业质检中的三维缺陷定位或者任何需要从点云中分离出独立物体的场景这个思路都值得仔细研究。它的代码结构清晰训练流程相对标准对硬件的要求也不算离谱——单卡就能跑起来这对个人开发者和小团队来说非常友好。2. 核心架构拆解为什么这样设计2.1 整体网络结构的选择逻辑这个项目的主干网络用的是U型编码器-解码器结构这在点云分割任务里是相当成熟的选择。编码器部分通过逐层下采样和特征提取把原始点云从高分辨率低维特征逐步压缩成低分辨率高维特征解码器再通过上采样和跳跃连接恢复分辨率。为什么选这个结构因为实例分割既需要全局的语义理解知道这是什么又需要局部的空间精度知道边界在哪U型结构恰好能兼顾这两点。具体到实现上编码器用了集合抽象层每一层做三件事采样、分组、特征聚合。采样用的是最远点采样保证采样点均匀覆盖整个空间分组用球查询在每个采样点周围找固定数量的邻居特征聚合则用小型多层感知机加最大池化。这套组合在PointNet里已经被验证过无数次了稳定可靠。解码器用的是特征传播层通过最近邻插值把低分辨率的特征上采样回原始点数再和编码器对应层的特征拼接。这里有个细节值得注意上采样用的是基于距离的加权插值而不是简单的最近邻复制。这样做的好处是特征过渡更平滑对边界区域的分割精度有明显提升。注意如果你打算复现这个项目主干网络部分建议直接用现成的PointNet实现不要自己从头写。集合抽象层里的球查询操作涉及大量的距离计算和排序自己实现很容易在效率上踩坑。2.2 边界框预测头的设计考量这是整个项目最核心的创新点。网络在解码器输出之后接了一个共享的多层感知机对每个点输出一组参数。这组参数包括包围盒的中心点坐标3维、三个轴的尺寸3维、以及一个方向角1维总共7维。另外还并行输出了一个语义分类分支用来判断每个点属于什么类别。为什么是这7个参数因为这是描述一个3D有向包围盒的最小参数集。中心点确定位置尺寸确定大小方向角确定朝向。你可能会问为什么不用8个角点来表示因为角点之间有约束关系直接回归角点容易产生不自洽的预测比如预测出来的8个点构不成一个合法的长方体。用中心尺寸角度的参数化方式天然保证了包围盒的合法性。方向角的回归有个经典难题角度的周期性。0度和360度是同一个方向但数值上差了360。如果直接回归角度值网络在边界处会产生巨大的损失波动。这个项目采用的做法是回归角度偏移量的正弦和余弦值或者用分箱分类残差回归的方式。前者更简单后者精度更高。我在实际测试中发现对于大多数场景正弦余弦回归已经够用了除非你的物体朝向分布特别集中。2.3 位置聚类的后处理机制网络输出每个点的包围盒预测之后后处理阶段要做的事情就是把预测相似包围盒的点聚成实例。具体流程是这样的首先根据语义分类结果把点按类别分开然后在每个类别内部计算每两个点之间包围盒参数的相似度最后用均值漂移或者带带宽的聚类算法把相似度高的点归为一组。这里的相似度度量很关键。项目里用的是包围盒中心点之间的欧氏距离加上尺寸和角度的加权差异。为什么中心点距离占主导因为同一个实例内的点它们预测的中心点应该都指向同一个位置方差很小而不同实例的中心点距离通常较远。尺寸和角度作为辅助约束用来处理那些中心点接近但实际是不同物体的情况比如叠在一起的两个箱子。聚类带宽的选择是个经验活。带宽太小同一个物体会被拆成多个实例带宽太大相邻物体会被合并。项目里给出的默认值在大多数数据集上表现不错但如果你的数据密度和物体尺度跟标准数据集差异较大这个参数必须重新调。3. 实操全流程从环境搭建到模型推理3.1 环境准备与依赖安装这个项目基于PyTorch框架建议用Python 3.7以上版本。我实测下来Python 3.8 PyTorch 1.10 CUDA 11.3这个组合最稳定。不要用太新的PyTorch版本因为一些自定义的CUDA算子可能没有适配。依赖安装分两步。先装基础科学计算库pip install numpy scipy scikit-learn pip install torch torchvision --index-url https://download.pytorch.org/whl/cu113然后装点云处理相关的库。这里有个坑有些库需要编译CUDA扩展对gcc版本有要求。建议用gcc 7.5到9.0之间的版本太新或太旧都可能编译失败。pip install open3d pip install plyfile提示如果你没有GPU或者GPU显存小于8GB训练阶段会非常吃力。推理阶段倒是可以在CPU上跑但速度会慢很多。我试过用CPU推理一个中等规模的场景大概需要十几秒而GPU上不到一秒。3.2 数据准备与预处理这个项目在标准数据集上训练数据格式是每个场景一个点云文件加一个标签文件。点云文件包含每个点的XYZ坐标可能还有RGB或法向量标签文件包含每个点的语义类别和实例ID。预处理阶段要做几件事。第一是体素下采样把原始点云降采样到固定点数比如每个场景采样到4096个点。这样做是为了控制显存占用和计算量。第二是归一化把点云坐标缩放到一个单位球内避免不同场景尺度差异过大影响训练。第三是数据增强包括随机旋转、随机缩放、随机抖动等。这里有个实操心得随机旋转的角度范围不要设太大。对于室内场景物体朝向通常和重力方向有明确关系如果旋转范围超过正负30度可能会产生不合理的姿态。对于室外场景可以放宽到正负180度因为车辆和行人的朝向本身就没有固定规律。3.3 训练配置与参数调优训练用的损失函数是多任务损失包括语义分类的交叉熵损失、包围盒中心点的回归损失、尺寸的回归损失、角度的回归损失。各项损失的权重需要仔细调。项目里给出的默认权重是分类损失占1.0中心点损失占1.0尺寸损失占0.5角度损失占0.5。为什么尺寸和角度的权重更低因为这两个量的数值范围比中心点小如果权重一样中心点的损失会主导梯度导致尺寸和角度学不好。这个权重比例是我试过比较合理的当然你可以根据自己数据的特点微调。学习率用余弦退火策略初始值设0.001训练200个epoch。批大小根据显存来定8GB显存大概能放4个场景16GB能放8个。如果显存不够可以用梯度累积来模拟大批量训练。# 优化器配置示例 optimizer torch.optim.Adam(model.parameters(), lr0.001, weight_decay1e-4) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max200)注意训练初期loss可能会有剧烈波动这是正常的。如果波动持续超过20个epoch还不收敛检查一下数据归一化是否做好以及学习率是否过大。3.4 推理与后处理实操推理阶段把点云输入网络得到每个点的语义类别和包围盒预测。然后按类别分组在每个类别内部做位置聚类。聚类的具体步骤是计算每两个点之间包围盒中心点的欧氏距离用均值漂移算法带宽设为0.2到0.5之间根据物体尺度调整把收敛到同一个模态的点归为一个实例对每个实例内的点取包围盒预测的中位数作为最终包围盒这里有个细节聚类之前要先过滤掉低置信度的点。语义分类的softmax概率低于0.5的点直接丢弃不参与聚类。这样做可以减少噪声点对聚类结果的干扰。后处理还有一个可选步骤实例合并。如果两个实例的包围盒IoU超过0.5且语义类别相同就把它们合并。这个步骤对于处理过分割问题很有效但要注意不要过度合并否则会把相邻的同类物体错误地合并成一个。4. 常见问题与排查技巧实录4.1 训练不收敛或loss震荡这是最常见的问题。我遇到过好几次排查下来原因无非几个。数据归一化没做好是最常见的点云坐标范围差异太大导致梯度爆炸。解决办法是确保每个场景的点云都缩放到单位球内并且减去质心。学习率过大是第二常见的原因把初始学习率降到0.0005试试。批大小太小也会导致loss震荡如果显存不够用梯度累积。还有一个隐蔽的原因包围盒标签的编码方式不一致。有些数据集的包围盒角度是弧度制有些是角度制有些是绕Z轴旋转有些是绕Y轴。如果编码方式搞错了网络永远学不会正确的角度。检查方法是把标签可视化出来看看包围盒朝向是否合理。4.2 实例分割结果过分割或欠分割过分割表现为一个物体被拆成多个实例欠分割表现为多个物体被合并成一个。这两个问题的根源都在聚类带宽上。带宽太小导致过分割带宽太大导致欠分割。我的经验是先用默认带宽跑一遍统计一下每个实例的点数分布。如果发现大量实例的点数很少比如少于50个点说明带宽太小如果发现某些实例的点数异常多比如超过场景总点数的30%说明带宽太大。根据统计结果调整带宽每次调整幅度不要超过0.1。另外语义分割的准确率直接影响实例分割的上限。如果语义分割把椅子和桌子混淆了后面的聚类再准也没用。所以如果实例分割效果不好先检查语义分割的混淆矩阵。4.3 包围盒预测偏差大包围盒预测偏差大通常有三个原因。训练数据中包围盒标注不一致比如有些标注是轴对齐包围盒有些是有向包围盒。损失函数权重不合理中心点损失权重过大导致尺寸和角度学不好。网络容量不够解码器的特征维度太低无法编码足够的几何信息。排查方法把预测的包围盒和真实包围盒都可视化出来看看偏差主要在哪。如果中心点偏检查中心点回归分支如果尺寸偏检查尺寸回归分支如果角度偏检查角度编码方式。4.4 推理速度慢推理速度慢通常是因为点云点数太多。下采样到4096个点是一个比较平衡的选择再少会损失精度再多速度下降明显。另外后处理阶段的聚类是CPU操作如果实例数量很多聚类会成为瓶颈。可以考虑用GPU加速的聚类实现或者减少不必要的距离计算。还有一个容易被忽略的点模型没有切换到eval模式。如果忘了调model.eval()BatchNorm和Dropout层会继续以训练模式运行不仅速度慢结果也不对。问题现象可能原因排查方法解决措施训练loss不下降学习率过大/数据未归一化检查输入数据范围降低学习率重新归一化过分割聚类带宽太小统计实例点数分布增大带宽0.1欠分割聚类带宽太大检查实例点数上限减小带宽0.1包围盒角度偏差大角度编码方式错误可视化包围盒朝向统一角度编码方式推理速度慢点数过多/未切eval模式检查点数配置下采样调用eval()4.5 显存不足的应对策略显存不足是个人开发者最常遇到的问题。降低批大小是最直接的办法但会影响训练稳定性。用梯度累积可以在小批量的情况下模拟大批量。混合精度训练能省不少显存PyTorch自带的AMP模块用起来很方便。减少点云点数也能省显存但会损失精度。如果以上方法都不行可以考虑冻结编码器的一部分层只训练解码器和预测头。这样做虽然会降低最终精度但至少能跑起来。等有条件了再用全量训练。# 混合精度训练示例 from torch.cuda.amp import autocast, GradScaler scaler GradScaler() with autocast(): outputs model(inputs) loss criterion(outputs, targets) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()5. 这个方案的实际应用场景与扩展思路5.1 自动驾驶中的障碍物分离在自动驾驶感知中激光雷达返回的点云包含车辆、行人、路障、建筑物等多种物体。语义分割只能告诉你这是车但规划控制模块需要知道前方有几辆车每辆车的位置和尺寸。这个方案可以直接输出每辆车的包围盒而且不需要额外的检测网络一套模型端到端搞定。实际部署时可以把推理和后处理放在车载计算平台上。由于模型参数量不大经过TensorRT优化后单帧推理可以控制在50毫秒以内满足实时性要求。5.2 工业质检中的缺陷定位工业场景中零件表面的缺陷凹坑、划痕、凸起需要被精确定位和分类。这个方案可以把每个缺陷当作一个实例输出缺陷的包围盒。相比传统的图像检测方法点云方案不受光照影响对反光表面和暗色表面更鲁棒。扩展思路是在包围盒预测头之外再加一个缺陷类型分类头直接输出缺陷的细分类别。这样一套模型同时完成检测和分类简化了流水线。5.3 机器人抓取中的物体位姿估计机器人抓取需要知道物体的6D位姿位置朝向。这个方案输出的有向包围盒已经包含了位置和朝向信息稍加转换就能得到抓取所需的位姿。对于堆叠场景位置聚类可以有效地把不同物体分开避免抓取时碰撞。一个实用的技巧是在包围盒预测头之后加一个位姿精修网络用包围盒内的点云做一次精细的位姿回归。这样可以在不增加太多计算量的情况下把位姿精度提升一个档次。5.4 后续改进方向这个方案虽然思路巧妙但也有明显的改进空间。聚类带宽的自适应选择是一个方向可以根据场景的密度分布自动调整带宽而不是用固定值。包围盒参数的相关性建模是另一个方向目前中心点、尺寸、角度是独立回归的但实际上它们之间存在相关性联合建模可能会提升精度。还有一个有意思的扩展把包围盒换成更一般的几何基元比如圆柱体、球体、甚至超二次曲面。对于某些特定类别的物体比如树干、管道用圆柱体表示比包围盒更紧凑回归精度也更高。我在实际项目里试过把包围盒换成圆柱体来检测树干效果确实比包围盒好尤其是对于倾斜的树干圆柱体的参数化更自然。当然这需要修改网络输出维度和损失函数工作量不小但收益是值得的。6. 一些踩坑之后的经验之谈这个项目我从头到尾复现过两遍第一遍踩了一堆坑第二遍才跑通。最大的教训是不要一上来就改网络结构。很多人觉得这个方案不够好想加注意力机制、加Transformer、加各种花哨的模块。我的建议是先把原版跑通把baseline的指标复现出来然后再动结构。否则你改了半天指标不升反降你都不知道是改的地方有问题还是原版就没跑对。第二个教训是后处理的调参比网络训练更耗时。网络训练虽然慢但至少是自动的后处理的聚类带宽、置信度阈值、实例合并阈值这些参数需要反复手动调。建议写一个自动化的评估脚本每次调参后自动跑一遍验证集输出指标这样效率高很多。第三个教训是可视化工具要提前准备好。点云的可视化不像图像那么直观你需要一个能交互旋转、缩放、切换视角的工具。Open3D自带的可视化功能就够用了但建议自己封装几个常用函数比如按实例着色显示包围盒对比预测和真值这样排查问题的时候能省很多时间。最后分享一个小技巧训练的时候定期保存中间模型的预测结果不要只看最终的指标。有时候指标看起来还行但可视化出来发现某些类别的分割效果很差。早发现早调整比训练完了再回头找问题要高效得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑