简介:围绕6D位姿估计这一机器人视觉核心任务整理的综述文献总结,面向从事机器人抓取、三维感知与位姿估计算法学习的研究生、工程师及技术选型人员,帮助快速建立从物体定位、姿态估计到抓取估计的知识框架。资源包仅含1个PDF文件,大小约434KB,以思维导图形式凝练综述论文要点,便于按图索骥梳理方法脉络。内容覆盖基于RGB-D、点云和RGB图像的三条技术路线,串联DenseFusion、MaskedFusion、PoseCNN、PointNet系列、VoxelNet以及PnP、模板匹配、关键点检测等代表性方法,并提示各自优势、局限与适用场景。已有3718人学习,适合用作论文阅读笔记、组会汇报提纲或算法调研索引,也可辅助对照原文查漏补缺。
1. 一份综述笔记抵得上两周试错:6D位姿估计的选型地图
6D位姿估计的翻车点,十有八九不在网络结构,而在你手上那份方法清单没法横向比较——输入换了、评测口径换了、数据集换了,最后拼出来的数字谁也不服谁。手头这份综述文献总结干的就是这件脏活:它按 RGB-D、纯点云、纯 RGB 三条输入路线切开,再叠上直接法/间接法、基于对应/基于模板/基于投票这两组正交维度,把 DenseFusion、MaskedFusion、PoseCNN、PointNet 系、PVNet、Pix2Pose、NOCS 这些代表工作钉在一条时间线上,还配了一张从「物体定位 → 位姿估计 → 抓取估计」贯通下来的思维导图。它适合三类人:准备复现但缺选型依据的、要写方案对比却只有一句「DenseFusion 效果好」的、被问「为什么不用关键点那套」问住的。落地场景很明确——机器人抓取、无序分拣、AR 注册,都是差几毫米就抓空的地方。
2. 把综述折成三张表:输入路线、求解范式与标注成本的交叉选型
选型之所以难,是因为大部分对比文章把「输入是什么」「怎么解」「标注要多贵」三件事揉成一段话讲。这份综述的真正价值是把它们拆成正交维度,你只要按顺序问自己三个问题,方法池就能从二十多个收到两三个:传感器给什么、误差想在哪一步修、标注预算够不够。
2.1 三条输入路线:先看传感器给什么,再看网络吃什么
RGB-D 这条线是工程落地最常见的选择,原因是它同时拿到了纹理和几何。DenseFusion 的做法是把 RGB 分支输出的颜色嵌入图和深度反投影点云经 PointNet 得到的几何嵌入图,按像素拼成一组稠密特征,每个像素都独立预测一个位姿和一个置信度,最后做加权聚合。这种 pixel-wise 的融合方式比全局拼接更抗遮挡——被挡住的那部分像素置信度低,自然在投票里权重就小。MaskedFusion 在这条路上又加了一路 mask 输入,把物体形状先验显式喂进去。PoseCNN 则是另一种思路:主体仍是 RGB,深度只在后端用 ICP 做精修。
纯点云路线的起点是 PointNet 系列。点云无序,用最大池化做对称函数聚合;点云有旋转歧义,用 T-Net 学一个变换矩阵把输入摆正;PointNet++ 再用多尺度分组解决点云密度不均。往检测方向走,Frustum-PointNet 先做 2D 检测框,把框对应的点云视锥抠出来再做 3D 分割和边界框回归,代价是它不是端到端;VoxelNet 走体素化路线,把点云切成体素后上 3D 卷积加 RPN,在车载公开数据集上表现领先,但体素化本身的量化误差和内存开销是硬伤。纯点云的优势是不吃光照和纹理,工业件上下料、金属件分拣这类场景很吃这一套;劣势是缺少表面信息,遇到几何细节少的物体,位姿里的旋转分量会明显飘。
纯 RGB 路线硬件最便宜,失败模式也最明确。传统特征匹配(SIFT/FAST/SURF/ORB 那一套)在弱纹理和严重遮挡下基本失效;模板匹配对低纹理物体友好,但场景混叠或物体形变就崩。深度学习方法里,直接回归位姿的(PoseCNN、SSD-6D、Deep-6DPose)搜索空间大、视角变化敏感;把任务解耦成「2D 关键点 + PnP」的间接方法(BB8、YOLO-6D、PVNet、分割驱动的局部位姿、Pix2Pose)鲁棒性更好,代价是没法端到端优化位姿。
| 输入路线 | 代表工作 | 核心优势 | 主要失败模式 |
|---|---|---|---|
| RGB-D | DenseFusion、MaskedFusion、PoseCNN+ICP | 纹理与几何互补,弱纹理下仍稳 | 深度图在反光/透明/黑色表面缺失,几何分支反而引入噪声 |
| 纯点云 | PointNet/++、Frustum-PointNet、VoxelNet、PPF、FPFH | 不受光照纹理影响,工业件友好 | 缺表面信息,遮挡与形变敏感,计算量大 |
| 纯 RGB | PoseNet、SSD-6D、BB8、PVNet、Pix2Pose、DPOD | 硬件便宜,部署门槛低 | 尺度歧义、低纹理性能骤降、遮挡下关键点漂移 |
提示:深度相机的工作距离和精度曲线要提前查。同一套 DenseFusion 参数,在 0.3 米和 1.2 米工作距离下的表现能差一个档次,这不是网络的问题。
2.2 直接法与间接法:误差从哪产生就在哪修
直接法把「图像进、位姿出」当成一个回归问题。网络输出通常是四元数加平移,损失函数对旋转用测地距离、对平移用 L2。它的好处是端到端、推理链路短;坏处是旋转的回归目标在 SO(3) 上不连续,四元数的双覆盖(q 和 -q 表示同一旋转)会让训练不稳定,对称物体更是灾难——同一个物体转 90 度看起来一模一样,损失却给出巨大惩罚。
间接法把问题拆成两步:先建立 2D-3D 或 3D-3D 对应,再用 PnP 或最小二乘解位姿。综述按「对应」的来源又分了三类。基于对应的方法是局部派,用特征点去匹配,速度快、鲁棒性尚可,但弱纹理和严重遮挡下直接失效。基于模板的方法是整体派,拿输入图和一堆渲染出来的模板比相似度,取最近似的模板位姿,对低纹理物体有效,但模板数量随视角分辨率指数增长,场景混叠和形变时也会崩。基于投票的方法是折中派:每个像素或每个 3D 点都往预定义的特征点上投一票,票数聚起来就是关键点位置,再转成对应关系。PVNet 就是典型——每个像素预测一个指向关键点的二维单位向量,RANSAC 阶段随机采样成对像素求射线交点当作关键点假设,投票选出最优,最后 PnP。遮挡下只要还有一部分像素可见,投票就能收敛,这是它比直接回归稳的根本原因。
这条分类线的实用价值在于:你确定了自己能接受的「误差修正点」在哪,方法就定了。深度图可信就走 RGB-D 融合加 refinement;有完整 CAD 且物体几何特征丰富就走点云配准加 ICP;只有单目相机就走关键点投票加 PnP,但要做好遮挡时精度掉一档的心理准备。
2.3 实例级与类别级:标注成本决定技术栈
实例级和类别级经常被混着讲,实际是两个完全不同的工程。实例级要求为每一个待抓取的物体准备 CAD 模型,位姿定义在「物体模型坐标系 → 相机坐标系」之间,LineMOD、YCB-Video 这类基准都是实例级。它的标注成本是「每个物体一次建模」,好处是精度容易做高,工业场景里 SKU 有限,这套完全够用。
类别级(NOCS 那条线)不要求逐实例建模,而是把一个类别内所有物体规范化到一个共享的坐标空间里,网络预测的是「像素 → 规范化坐标」的映射,再从这个映射里解出位姿和尺寸。它的价值是能处理没见过的实例,代价是精度上限被类别内的形状差异吃掉一部分。综述里把这条线单独拎出来放在时间线尾部,意思很清楚:这是趋势,但不是当下抓取产线的第一选择。
落到具体项目上,判断标准就一条——你的物体集合是不是封闭的。封闭就老老实实做实例级,别被类别级的新颖性带偏;开放集合才值得投入类别级的标注和训练成本。
3. DenseFusion 的 pixel-wise 融合与 refinement:两阶段训练的收敛顺序不能反
RGB-D 融合这条线上,DenseFusion 是绕不开的基线,它的两个设计——稠密像素级融合和迭代 refinement——在复现时最容易出问题的地方,恰好都不是网络结构本身。前者取决于你的反投影有没有和内参对齐,后者取决于你的训练顺序有没有排对。
3.1 颜色嵌入和几何嵌入怎么对齐成同一组像素
融合要成立,前提是两路特征在同一个像素索引上说的是同一个物理点。RGB 分支经过骨干网络和上采样,输出 H×W×128 的颜色嵌入;几何分支要先把深度图按内参反投影成 H×W×3 的像素级点图,再送进 PointNet 类的编码器得到 H×W×128 的几何嵌入。反投影这一步是整个流程的地基:
x = (u - cx) * d / fx y = (v - cy) * d / fy z = d其中(u, v)是像素坐标,(cx, cy, fx, fy)是相机内参,d是该像素的深度值。这里有个容易被忽略的细节:如果你用检测框把目标区域裁出来再送网络,那么裁切后的像素坐标已经变了,反投影必须带上裁切偏移量,否则点云整体会平移一个框的位置,融合出来的特征全是错的。深度值为 0 的无效像素要显式屏蔽,不然反投影会得到原点附近的一堆垃圾点,把几何分支的池化结果带偏。
| 张量 | 形状 | 说明 |
|---|---|---|
| rgb_crop | B×3×H×W | 按检测框裁切并缩放后的彩色图 |
| depth_crop | B×1×H×W | 与彩色图逐像素对齐的深度图,单位统一为米 |
| pts | B×3×H×W | 反投影得到的像素级点图,无效深度置零并加掩码 |
| color_emb | B×128×H×W | RGB 分支上采样后的颜色嵌入 |
| geo_emb | B×128×H×W | 点云编码器输出的几何嵌入 |
| fused | B×256×H×W | 按通道拼接的稠密融合特征 |
3.2 refinement 模块:为什么必须等主网络收敛再训残差
refinement 模块的输入不是原始点云,而是「用上一轮预测的位姿把当前帧点云变换到模型坐标系之后」的点云。这一步很关键:它让网络不用再从零回归一个绝对位姿,只回归「还差多少」。迭代两轮是常见配置,第一轮的输出作为第二轮的初值,PointNet 提取变换后点云的全局特征,回归一个残差位姿,再乘回上一轮的结果上。
问题就出在这里——残差学习的目标分布完全依赖主网络的输出质量。主网络还在乱飘的时候,refiner 看到的输入是随机变换过的点云,它学到的「残差」其实是噪声的补偿,等主网络收敛了,这个补偿就变成负数贡献。血泪经验是:refiner 一定要在主网络收敛后单独开训,主网络冻结,学习率降到主网络的十分之一左右,验证集上对比「加 refiner 前」和「加 refiner 后」两组数字,只要有一组变差就说明顺序或者学习率有问题。
注意:有些复现脚本图省事,把主网络和 refiner 放进同一个优化器一起训,loss 曲线看起来也在降,但评测指标就是上不去。这种「看起来能跑」的配置是最费时间的坑。
3.3 MaskedFusion 多喂一路 mask:训练时间换精度的账怎么算
MaskedFusion 在 DenseFusion 基础上改的是数据入口:不再是「RGB + 深度」两路,而是「裁切后的 RGB + 裁切后的深度 + 裁切后的实例掩码」三路一起进网络。掩码携带的是物体的形状先验,在纹理缺失和被遮挡的区域,这一路信息能补上颜色分支的判断。综述里的结论是训练时间变长、精度更高、推理时间基本不变——推理不变的原因是三路编码是并行的,融合层只多一次通道拼接,计算增量远小于训练时的反向传播开销。
复现时真正要算的账不是训练时长,而是掩码从哪来。训练阶段用真值掩码、推理阶段用分割网络输出,这个域差会直接吃掉一部分精度增益。常见做法是训练时对掩码做随机腐蚀、膨胀和边缘抖动,让网络见过不完美的掩码;更彻底的做法是训练阶段就用检测分割网络的输出重新跑一遍。这一步做不做,决定了 MaskedFusion 在你手里是「比 DenseFusion 高两个点」还是「比 DenseFusion 低一个点」。
# 仅示意张量流转与投票逻辑,不对应任何具体实现 H, W = 224, 224 color_emb = rgb_encoder(rgb_crop) # [B, 128, H, W] pts = backproject(depth_crop, K, offset) # [B, H*W, 3] 带裁切偏移的反投影 geo_emb = pointnet_encoder(pts) # [B, 128, H, W] fused = torch.cat([color_emb, geo_emb], dim=1) # [B, 256, H, W] seg_logit = seg_head(fused) # [B, 2, H, W] 自监督像素级分割 pose_per_px = pose_head(fused) # [B, 7, H, W] 四元数(4) + 平移(3) conf = conf_head(fused) # [B, 1, H, W] 每像素置信度 # 置信度既参与训练加权,也参与推理聚合 pose = weighted_vote(pose_per_px, conf, seg_logit)这段流程里三个参数最需要动手调:H, W决定了几何分支的点数,224 是速度和精度的常见折中,降到 128 会让小目标的关键点信息丢失;offset是裁切框左上角在原图中的坐标,漏了它点云就整体错位;conf参与损失的加权方式要固定,训练用加权 L1、推理用加权聚合,两边口径不一致会让评测数字虚高。seg_logit那一路是无监督的辅助任务,它不直接产生位姿,但给投票提供了像素筛选依据,去掉之后遮挡场景的精度会明显下滑。
4. PoseCNN 的三头输出与关键点投票系:后端 PnP/ICP 怎么接才不掉精度
如果 DenseFusion 代表的是「融合到底」,PoseCNN 和 PVNet 代表的是另一种工程哲学:网络只负责把问题简化到一个可解的几何形式上,剩下的交给经典算法。这种分工的好处是可解释、可调试,坏处是后端那一步的参数给不好,前面网络的精度会被白扔掉一大半。
4.1 PoseCNN 三头:语义分割、3D 平移、3D 旋转
PoseCNN 用一个 VGG16 骨干接三个任务头。语义分割头做像素级分类,同时回归每个像素指向物体中心的单位向量,两者结合求出物体的 2D 中心;3D 平移头在中心像素处回归到相机的距离,配合内参反投影就得到平移向量;3D 旋转头直接回归四元数。三个头里最容易出问题的是旋转头,原因是损失函数。
对称物体的位姿估计是这条线上的经典难题:一个圆柱转 90 度和不转,在图像上完全一样,但四元数差得远,普通 L2 或测地距离损失会给出一个巨大的惩罚,网络学到最后只能输出一个「平均姿态」,测试时怎么调都不对。PoseCNN 引入的 ShapeMatch-Loss 就是针对这个:在物体的对称变换集合里取最小值,只要预测结果等价于某个对称变换后的真值,损失就是零。换句话说,它不再要求网络猜中「哪一个等价旋转」,只要求猜中「旋转所在的等价类」。
网络出完结果之后,还可以用深度图接一次 ICP 精修。这一步对遮挡物体的提升最明显,因为分割头在遮挡边界上经常出错,而点云配准只关心几何重合度,两者的错误模式不相关,串起来能互补。
4.2 PVNet 的方向向量场与 RANSAC 投票
PVNet 把位姿估计彻底解耦。第一阶段,每个像素预测两个东西:一个是语义标签(属于目标还是背景),另一个是指向物体各个关键点的二维单位向量。第二阶段,在目标区域内随机采样成对像素,每个像素的向量定义一条射线,两条射线求交就得到一个关键点的位置假设;重复若干次,用 RANSAC 选出内点最多的那个假设作为该关键点的估计;拿到全部关键点的 2D 坐标后,用 PnP 解位姿。
这套设计对遮挡的鲁棒性来自投票机制本身:物体被挡住一半,剩下那半边的像素仍然指向同一个关键点,射线依然能交到正确位置。相比之下,直接回归位姿的网络在遮挡下只能靠「猜」。它的短板也清楚:低纹理或者低分辨率图像里,方向向量的预测本身就不准,投票再稳也没用;另外它是两阶段的,位姿不是端到端优化出来的,后端 PnP 的误差不会被反传回网络。
4.3 后端精配准:ICP 与 PnP 的参数给法
PnP 这一步常见做法是用带 RANSAC 的版本,因为关键点检测难免有离群点。三个参数需要按场景给:重投影误差阈值决定什么算内点,一般取 3 到 8 像素,噪声大的相机往上调;迭代次数和置信度是一对,0.99 的置信度配 1000 次迭代在多数场景够用;求解标志位选 EPnP 适合点数多且分布散的情况,点数少(4 到 6 个)时用 AP3P 更稳。关键点数量少于 4 个直接失败,共线分布也会让解退化。
import cv2 import numpy as np # object_points: N×3 的模型坐标系关键点 # image_points: N×2 的像素坐标,顺序必须与 object_points 一一对应 ok, rvec, tvec, inliers = cv2.solvePnPRansac( object_points, image_points, camera_matrix=K, dist_coeffs=dist, iterationsCount=1000, # 内点少时往上加 reprojectionError=5.0, # 像素单位,噪声大就放宽 confidence=0.99, flags=cv2.SOLVEPNP_EPNP, # 点数少时换 SOLVEPNP_AP3P )ICP 那一步的坑集中在初值和搜索距离。初值一般直接拿 PnP 的结果,或者上一帧的位姿;搜索距离max_correspondence_distance要跟模型尺寸挂钩,常见取法是模型包围盒最大边长的 5% 到 10%,取太大场景里的背景点会被拉进来,取太小初值稍微偏一点就找不到对应。点到面(PointToPlane)比点到点收敛快,但要求点云带法线,法线估计的邻域半径又要和点间距匹配,多一层参数就多一层出错机会,赶时间的话先用点到点跑通再说。
import open3d as o3d # src: 场景中分割出来的目标点云;tgt: 模型点云(或渲染出的模板点云) reg = o3d.pipelines.registration.registration_icp( src, tgt, max_correspondence_distance=0.01, # 单位与点云一致,按模型尺寸缩放 init=init_transform, # 来自 PnP 或上一帧 estimation_method=o3d.pipelines.registration .TransformationEstimationPointToPoint(), criteria=o3d.pipelines.registration.ICPConvergenceCriteria(max_iteration=50), ) T_refined = reg.transformationinit_transform传错坐标系是最高频的翻车点:PnP 解出来的通常是「模型 → 相机」,而 ICP 要的是「场景点云 → 模型点云」,两者之间差一个求逆。跑之前先拿单位阵试一次,看输出的 fitness 是不是接近 1,如果不是,先怀疑方向,别怀疑参数。
5. 复现排查:位姿误差降不下去的五个高频坑
位姿估计的调试不像分类任务,accuracy 不动就换个学习率。它的误差来源分散在相机标定、点云构造、损失函数、坐标变换、评测口径五个环节,任何一环错了,现象都长成「精度上不去」这一副面孔。下面五条是复现这条线上最常见的,每条都按现象、原因、解决拆开。
5.1 数据与标注侧的两个坑
坑一:反投影出来的点云和 RGB 对不上。现象是可视化时点云轮廓明显偏移,融合特征的训练 loss 卡在一个不低的位置下不去。原因多半是内参和采集时不一致,或者彩色图和深度图分辨率不同却没有做对齐,直接按索引硬拼。解决办法是把深度图先重投影到彩色相机坐标系,统一分辨率之后再算;裁切增强的话,把裁切偏移量显式记录并传进反投影函数,别在裁切后的局部坐标上直接用全局内参。
坑二:对称物体旋转误差怎么训都下不来。现象是平移误差正常,旋转误差在对称轴上恒定偏大,评测里 ADD 很差但 ADD-S 还行。原因是用了普通测地距离损失,物体的等价旋转被当成错误惩罚。解决办法是换成对对称集合取最小值的损失,或者在数据加载阶段对真值旋转做规范化,保证同一等价类只有一个标签。圆柱、方形盒、带旋转对称的工件都属于这一类,LineMOD 里就有两个典型。
提示:先看 ADD 和 ADD-S 的差距,差距大基本可以确定是对称性问题,不用去调学习率。
5.2 训练与推理侧的两个坑
坑三:加了 refinement 反而变差。现象是主网络单独评测的指标正常,接上 refiner 之后整体下降,或者在不同随机种子下结果波动很大。原因是主网络没收敛就开了 refiner 的训练,或者两者共用一个优化器和学习率。解决办法是分两阶段:主网络训到验证集指标平稳,冻结参数,再单独训 refiner,学习率取主网络的十分之一,每轮都在验证集上对比加与不加的结果。
坑四:换一个场景精度暴跌。现象是训练集和同分布测试集表现很好,换条产线或者换个工位就崩。原因通常是训练时喂的是真值掩码和真值检测框,推理时换成检测分割网络的输出,输入分布变了。解决办法是在训练阶段就对掩码和框做随机扰动(腐蚀、膨胀、抖动几个像素),或者干脆用检测器跑一遍训练集,把带噪声的掩码当作训练输入。
5.3 评测口径里的一个坑
坑五:训练 loss 正常,2cm/5cm 召回率极低。现象是 loss 曲线漂亮,一算阈值召回率只有个位数,但把预测位姿可视化出来看着又挺对。原因一般是评测时的参考系和训练时不一致,或者单位没统一(模型用毫米、位姿用米)。解决办法是写一个单样本的回投检查:把预测位姿作用到模型点云上,投影回图像,和原图叠一起看,偏移一目了然。这个检查我每次换数据集都跑,比看任何指标都快。
注意:ADD 和 ADD-S 的阈值不要混用。2cm/5cm 那套召回率是给特定数据集定的口径,换数据集要先确认别人用的是直径比例还是绝对距离,否则横向对比没有意义。
6. 把综述变成验证清单:ADD/ADD-S 口径核对与文献阅读顺序
综述类的资源最容易读完就忘,因为它给的是地图不是路线。我自己的用法是把它拆成两张清单:一张是评测口径核对表,一张是阅读顺序表。
| 指标 | 计算方式 | 适用对象 | 常见误用 |
|---|---|---|---|
| ADD | 模型点经预测位姿与真值位姿变换后的平均距离 | 非对称物体 | 直接套到对称物体上,指标永远难看 |
| ADD-S | 取最近点距离的平均值 | 对称物体 | 拿它和非对称物体的 ADD 横向比 |
| 2cm/5cm 召回 | 误差小于阈值的样本占比 | 数据集内横向比较 | 换数据集不换口径,数字不可比 |
| 旋转误差 | 测地距离,单位度 | 单看旋转质量 | 忽略四元数双覆盖导致的正负号问题 |
阅读顺序上,先看思维导图建立分类骨架,再按你选的输入路线各挑两篇代表作,重点读它们的「失败分析」章节而不是「结果」章节,最后回到综述的评测部分核对口径。这个顺序能让你在两三天内建立起「哪类方法在什么条件下会崩」的判断力,比按时间顺序从头读到尾有效得多。
有一个技巧值得单独说:把你打算复现的方法,在综述的时间线上找它前后的各一篇,看后一篇在「局限」里怎么评价它。综述的作者通常会把这类批评提炼得很准,比你自己跑两周实验发现得快。
从那以后我每接一个位姿项目,都强制先跑一遍单样本回投可视化,再看 ADD 和 ADD-S 的差距,最后才动手改网络。顺序反过来的代价,我付过不止一次。希望帮到你。
本文还有配套的精品资源,点击获取