点序本身就是数据
imagePoints[i] 必须观测 objectPoints[i]。对称点换位会产生几何上自洽但语义错误的姿态。
2D–3D Correspondence & Perspective-n-Point
PnP 用已知相机模型和一组“模型点—图像像素”对应,恢复将物体或世界坐标变到相机坐标的旋转与平移。真正决定系统上限的往往不只是求解器名称,而是对应是否正确、几何是否可观、RANSAC 是否合理,以及最终优化是否仍使用一致的成像模型。
Problem Contract
本站沿用右手系、列向量和 OpenCV optical frame。给定物体系中的 3D 点 Pi、对应像素 pi、相机内参 K 与畸变 D,PnP 求解 ^C R_O 与 ^C t_O,使变换后的模型点通过同一相机模型投回观测像素。
未知量虽然是 6 个,但旋转带非线性正交约束,不能只靠“每点两条方程”粗暴计数。
三条已知 3D 点间距离与三条相机 bearing 约束可求最小问题,但通常存在多个离散候选。
实际接口常要求或建议第四个对应,用它验证与排序 P3P 候选;不同 API 的点数约定要单独核对。
更多且分布良好的对应提供冗余,可做鲁棒估计、加权与非线性优化。
Where Correspondences Come From
对应可能来自人工标记、特征匹配、语义关键点或稠密物体坐标。它们的噪声、相关性、空间布局和错误模式不同,因此应使用不同的采样、权重与质量诊断。
| 对应来源 | 3D 侧 | 2D 侧 | 优势 | 主要风险 |
|---|---|---|---|---|
| 语义关键点 | CAD 上预定义角点、孔位、轴端点 | 网络热图或坐标回归 | 语义清晰、对应数量少 | 遮挡、对称点交换与布局集中 |
| 局部特征匹配 | SfM / CAD 纹理上的 3D 特征 | SIFT、SuperPoint 或基础模型特征 | 适合相机重定位与纹理物体 | 重复纹理与错误匹配需要强鲁棒估计 |
| 稠密物体坐标 | 每个前景像素对应 CAD / NOCS 坐标 | 像素网格或采样后的前景点 | 对应多、覆盖广、适合学习系统 | 相邻像素误差相关,不能把数量等同于独立信息量 |
| 人工标记 / 平面板 | 已知方形角点或标定板坐标 | 亚像素角点检测 | 精度高、工程可控 | 严格共面且常有两个姿态候选 |
| 渲染 / 模板匹配 | 候选姿态下的表面点或轮廓 | 观测边缘、mask 或特征位置 | 可与迭代精修结合 | 对应会随位姿更新,属于交替优化问题 |
imagePoints[i] 必须观测 objectPoints[i]。对称点换位会产生几何上自洽但语义错误的姿态。
稠密坐标误差在局部高度相关,应采样、聚类或按预测不确定性加权。
分散到物体不同面、图像不同区域的少量点,可能比集中在局部的更多点更稳定。
自遮挡、截断和外部遮挡会改变可用点集合;训练与推理应保持同一可见性语义。
Solver Taxonomy
选择求解器时先看最小样本、点的三维布局、是否需要多解、是否用于 RANSAC,以及后面是否还有迭代精修。不要只根据一个 benchmark 的平均速度选择。
| 求解器 | 点数 | 几何 | 候选 | 典型角色 | 注意事项 |
|---|---|---|---|---|---|
| P3P / AP3P | 理论 3;常用接口以第 4 点消歧 | 非共线最小集 | 最多 4 个候选 | RANSAC 候选生成;AP3P 是更高效稳定的代数实现 | 必须枚举并用额外点、正深度与残差排序 |
| EPnP | n ≥ 4 | 一般点;也可处理平面情形 | 通常返回一个 | O(n) 非迭代通用初值,大量对应时常用 | 有噪声、小样本或病态布局时仍建议非线性精修 |
| SQPnP | n ≥ 3 | 一般与共面点 | 可返回多个最优候选 | 快速、全局最优的通用求解器 | “全局最优”针对其目标,不会修复错误对应、错误 K 或物体对称歧义 |
| IPPE | n ≥ 4 | 必须共面 | 显式返回 2 个 | 平面目标、AR marker 与标定板 | 近正视、小目标时双解残差可能很接近 |
| IPPE_SQUARE | 严格 4 点 | 正方形且点序固定 | 显式返回 2 个 | 方形 marker 的专用快速解 | 尺寸、原点和四个角的顺序必须完全符合接口定义 |
| ITERATIVE / LM | 通常 n ≥ 4;初始化要求依接口而定 | 一般点或共面点 | 依初值进入局部解 | 最小化像素重投影误差,常用于最终精修 | 不是全局初始化器;初值、鲁棒损失和参数化会影响收敛 |
错误对应较多时,用小样本快速提出候选,再由全体对应评分。
无明显离群、点数较多时生成通用初值;随后仍应检查正深度并精修。
主动保留两个候选,而不是让通用单解接口静默选择错误分支。
在可信初值与内点集上最小化重投影目标,加入权重、鲁棒核或先验。
Interactive Lab
第一个视图观察像素残差与阈值如何形成共识集;第二个视图用精确公式计算不同最小样本大小的 RANSAC 预算;第三个视图比较空间、共面、近共线与集中布局。交互刻意把“求解器实现”和“所有 PnP 共享的鲁棒估计逻辑”分开。
Interactive · PnP & Robust Estimation
Consensus
Residual
Coverage
Pose contract
One draw
Required
Current budget
Verdict
RANSAC Is a Pipeline
标准流程是最小集提出假设、全数据建立共识、动态预算、局部优化,再用全部内点重估。阈值、样本大小和几何退化检查共同决定鲁棒性与速度。
从全部 2D–3D 对应中随机抽取 s 个点;在抽样前拒绝重复点、近共线点和明显病态布局。
P3P/IPPE 可能返回多个姿态。每个候选都要检查旋转合法性、正深度与数值有限性。
用同一 K、畸变模型和像素坐标计算重投影残差,以阈值 τ 构造共识集;可结合置信度或协方差。
按内点数、截断代价或 M-estimator 排序;由当前最佳内点率估计所需迭代数,提前终止。
不要把最小集解直接作为最终结果。用全部内点重新求解、更新内点,再做 LM/VVS 或 BA 式精修。
同时记录内点数、内点率、RMS/分位数、图像覆盖、最小深度、候选间距与终止原因。
Degeneracy & Ambiguity
严格共面目标不是天然不可解:它可以通过平面单应性或 IPPE 求姿态,但常需要处理两个候选。近共线点则缺少关键方向约束;局部集中点可能数学满秩,却因条件数差而把像素噪声放大为明显位姿误差。
检查中心化 3D 点协方差的第二特征值,或三角形面积;继续增加同一直线上的点没有帮助。
正视、远距离、小目标时两个候选的重投影误差可能接近,需要时序、非共面点或任务先验消歧。
扩大 3D 基线和图像凸包通常比单纯提高点数更有效,尤其能改善平面外旋转与深度。
若两个模型点在观测上不可区分,应输出等价姿态、多假设或使用对称感知评分,而不是强迫唯一标签。
Refinement & Uncertainty
最终优化应使用与观测生成一致的投影函数,可选鲁棒损失、关键点协方差、姿态先验与时间先验。它改善局部精度,却不能从错误分支或严重错误对应中自动恢复。
优化雅可比的谱可以揭示哪些姿态方向约束弱;残差小不代表每个自由度都可信。
平面或对称场景应保留多个候选及其分数,让跟踪、深度或机器人任务在后续消歧。
远处小物体可能重投影很好但深度不准;抓取应进一步评估 TCP、碰撞和接近方向误差。
Across Application Domains
模型点来自物体系,输出 CTO。常与检测、分割、关键点或稠密对象坐标网络组合。
3D 地图点与当前帧特征匹配后得到 CTW;用于轨迹输出时通常再求逆为 WTC。
PnP 只给视觉相对位姿,还要通过手眼外参变到 base / end-effector,并统一米、毫米和时间戳。
方形标记适合 IPPE_SQUARE;实际显示还需候选消歧、时序滤波和 OpenCV→图形学坐标转换。
Engineering recipe · OpenCV Python
ok, rvec, tvec, inliers = cv2.solvePnPRansac(
object_points, image_points, K, dist_coeffs,
iterationsCount=1000,
reprojectionError=3.0,
confidence=0.999,
flags=cv2.SOLVEPNP_AP3P,
)
if ok and inliers is not None and len(inliers) >= 4:
ids = inliers[:, 0]
rvec, tvec = cv2.solvePnPRefineVVS(
object_points[ids], image_points[ids],
K, dist_coeffs, rvec, tvec,
) 显式检查 float32/float64、N×3、N×2 和连续内存;不要让 squeeze 后的单点破坏形状。
平面或最小问题需要 solvePnPGeneric 枚举候选,再按任务信息排序。
重新投影并记录 inlier 分位数、凸包、最小 Z、det(R) 与候选间的旋转/平移差。
Debug Protocol
PnP 的错误经常来自前后处理:点序交换、resize 后 K 未更新、畸变状态混用、CAD 单位错误或输出方向读反。用可视化重投影和分层断点比盲目切换 flag 更有效。
若真值都无法落到 imagePoints,错误在点序、K/D、图像变换、坐标系或标注,不在 PnP。
一致方向的整体偏移常提示主点/裁剪错误;边缘径向误差提示畸变;少量超长箭头提示错配。
OpenCV rvec/tvec 将模型点送到相机系。需要 camera pose 时使用 Rᵀ 和 −Rᵀt,而不是只给 t 加负号。
大多数可见模型点应有 Z > 0。负深度候选应拒绝;只有少数可见点时需结合裁剪和遮挡解释。
对中心化 3D 点做 SVD,计算图像凸包;“内点很多但都集中”仍可能是弱约束。
平面和 P3P 场景先取全部候选;错误分支不是增加 LM 次数就能跨越的局部小问题。
固定完全相同的输入、内点集、精修方式和输出方向,再比较速度、失败率与任务误差。
Next geometry topic · 07