手眼标定与相机内外参标定 报告(理论模型、主流算法)
手眼标定与相机内外参标定 报告(理论模型、主流算法)
手眼标定与相机内外参标定 报告(理论模型、主流算法)
机器人视觉 · 标定专题研究
手眼标定与相机内外参标定
理论模型、主流算法、OpenCV 实现与工程验证
INTRINSIC × EXTRINSIC × HAND–EYE
项目
说明
报告类型
技术研究报告 / 工程实施指南
研究对象
单目工业相机、机器人末端与工作站坐标系
算法范围
Zhang、PnP、Tsai–Lenz、Park–Martin、Horaud、Andreff、Daniilidis、Shah
实现基线
Python + OpenCV calib3d(以 4.13.0 文档为参照)
编制日期
2026 年 8 月 4 日
适用场景:机器人抓取、装配、视觉引导、三维测量、视觉伺服与数字孪生坐标对齐。
摘要与核心结论
机器人视觉系统要把图像中的观测转成机器人可执行的空间坐标,至少要完成三层标定:相机内参用于描述成像几何和镜头畸变;相机外参用于描述目标坐标系与相机坐标系之间的刚体变换;手眼标定用于建立相机与机器人末端或机器人基座之间的固定变换。三者不是互相替代的关系,而是一条串联的数据链。任何一个环节的坐标方向、单位或时间戳出错,都可能造成厘米级甚至完全发散的抓取误差。
结论 01 工程上不应只比较某个算法输出的矩阵数值,而应比较独立验证集上的闭环误差、旋转测地误差、平移误差和最终任务空间误差。
结论 02 数据几何通常比算法名称更重要。手眼数据必须包含绕至少两个不平行轴的显著旋转,并同时覆盖不同平移与景深;相机内参数据要覆盖画面中心、四角、不同距离和倾角。
结论 03 建议将 Park 方法作为稳定基线,同时运行 Tsai、Horaud、Andreff、Daniilidis;以留出位姿的闭环一致性与真实抓取/触碰实验选型。Eye-to-Hand 若同时未知“相机到基座”和“标定板到末端”,优先按 AX=ZB(Robot–World / Hand–Eye)联合求解。
图 1 从图像与机器人位姿到可验证手眼结果的完整数据链
报告结构
- 第 1 章:问题定义、坐标系和齐次变换记号
- 第 2 章:相机内参标定——模型、张正友法、采集与质量评价
- 第 3 章:相机外参标定——PnP、变换方向与固定工作站外参
- 第 4 章:Eye-in-Hand / Eye-to-Hand 方程推导
- 第 5 章:五类 OpenCV 手眼算法与联合标定方法比较
- 第 6–8 章:工程流程、实验设计、代码模板与故障排查
- 附录:数据格式、验收清单、核心推导与参考文献。
1 问题定义与统一坐标记号
1.1 三类标定分别解决什么问题
标定类型
关系对象
典型输出
作用
失效条件
相机内参标定
相机内部
K、畸变系数 d
像素射线、去畸变、度量成像
焦距/焦点/分辨率改变后通常要重标
相机外参标定
目标/世界 ↔ 相机
R、t 或 4×4 齐次矩阵
已知三维点与二维观测之间的位姿
相机或参考物相对位置改变后重标
手眼标定
相机 ↔ 末端/基座
^gT_c 或 ^bT_c
把视觉结果映射到机器人坐标系
相机安装、法兰、支架发生变化后重标
内参标定输出的每幅图 rvec/tvec 是“标定板到相机”的逐帧外参,它不是手眼矩阵;手眼矩阵在相机与末端刚性连接不变时应当是唯一常量。
1.2 齐次变换的方向约定
本文统一采用 ^aT_b 表示“把 B 坐标系中的点变换到 A 坐标系”。列向量约定下:
^a p = ^aT_b · ^b p, ^aT_c = ^aT_b · ^bT_c, (^aT_b)⁻¹ = ^bT_a
T = [ R t ; 0 1 ], T⁻¹ = [ Rᵀ −Rᵀt ; 0 1 ]
旋转矩阵不能只取负号;平移的逆必须同时乘以 Rᵀ。
最常见的致命错误 机器人 SDK 可能返回“基座中的末端位姿” ^bT_g,也可能返回其逆;OpenCV solvePnP 返回“物体/标定板到相机” ᶜTt。两者方向不能凭变量名猜测,必须用一个已知点做正向变换验证。
1.3 坐标系定义
符号
英文
含义
典型状态
{b}
robot base
机器人基座坐标系
固定
{g}
gripper / tool
末端法兰或工具坐标系
随机器人运动
{c}
camera
相机光心坐标系
随安装方式而定
{t}
target
棋盘格、圆点板或 ChArUco 标定板坐标系
Eye-in-Hand 固定;Eye-to-Hand 常装在末端
{w}
world
工作站/测量世界坐标系
可与 {b} 或 {t} 重合,也可独立
图 2 针孔模型中的三维点、像平面和相机内外参
2 相机内参标定
2.1 成像模型与参数
s [u v 1]ᵀ = K [R | t] [X Y Z 1]ᵀ
K = [ fₓ γ cₓ ; 0 fᵧ cᵧ ; 0 0 1 ]
其中 fₓ、fᵧ 是以像素为单位的焦距,(cₓ,cᵧ) 是主点,γ 是像素轴倾斜量(现代相机通常近似为 0)。K 只描述理想针孔投影;真实镜头还要用畸变模型修正归一化坐标。
x′ = x(1+k₁r²+k₂r⁴+k₃r⁶)+2p₁xy+p₂(r²+2x²)
y′ = y(1+k₁r²+k₂r⁴+k₃r⁶)+p₁(r²+2y²)+2p₂xy
OpenCV 常用 Brown–Conrady 模型,基本参数为 k₁、k₂、p₁、p₂、k₃;高阶 rational 模型可再加入 k₄–k₆,薄棱镜模型可加入 s₁–s₄,倾斜传感器模型可加入 τₓ、τᵧ。鱼眼镜头应优先使用 cv.fisheye 模块,不要强行用普通透视模型吸收超广角畸变。
2.2 张正友平面标定法
张正友法使用一个几何尺寸已知的平面模板,从多个未知姿态拍摄。每个姿态建立平面到图像的单应矩阵 H;利用旋转矩阵列向量正交且等长的约束,线性求出与 K 相关的对称矩阵,再恢复内参。随后恢复每一幅图的 R、t,并用最大似然意义下的非线性优化联合最小化重投影误差。原论文指出理论上少量姿态即可求解,但实际建议使用更多、几何分布更好的姿态。
- 建立标定板平面点 Pᵢ=(Xᵢ,Yᵢ,0),检测对应像素点 pᵢ。
- 每个视角估计单应矩阵 H,使 p ~ H·P。
- 由 H 的列向量约束构造线性方程,求取 K 的初值。
- 由 K⁻¹H 恢复各视角外参 R、t,并把近似旋转投影到 SO(3)。
- 联合优化 K、畸变参数和所有外参,使总重投影误差最小。
2.3 标定板选择
类型
优点
主要风险
适用
棋盘格
结构简单、成本低、资料多
局部遮挡会导致整板检测失败;黑白边界反光敏感
普通实验室与教学
圆点阵列
圆心亚像素定位稳定,适合工业打印/加工板
必须确认对称/非对称阵列定义与点序
高重复性工业标定
ChArUco
ArUco 身份编码 + 棋盘亚像素精度,可部分可见
板字典、尺寸和边界定义必须严格一致
手眼标定和大姿态变化
AprilGrid
标签身份明确,遮挡鲁棒,工具链成熟
与 OpenCV 原生流程的接口需额外实现
多传感器与科研系统
尺寸原则 算法中填入的是相邻角点或标记的实际几何尺寸,而不是外框尺寸。只要全流程单位一致,结果单位可用 m 或 mm;但手眼计算中相机 tvec 与机器人平移必须统一。
2.4 图像采集设计
图 3 内参和手眼数据都需要丰富的空间几何覆盖
- 固定焦距、焦点、分辨率、裁剪、缩放、binning 和 ISP 几何设置;自动对焦与电子防抖应关闭。
- 建议采集 15–30 张有效图像;数量只是起点,必须覆盖中心、四角、近距、远距和正负倾角。
- 让标定板占据画面较大比例,同时保留一部分边缘视角以约束径向畸变。
- 避免所有图都近似正对相机;至少包含绕水平轴和竖直轴的明显倾斜。
- 避免运动模糊、过曝、欠曝、打印纸翘曲和反光;高精度任务使用刚性加工板。
- 若后续工作温度、对焦距离变化显著,应按工作状态分组标定或建模温漂。
2.5 内参质量评价
eᵢ = ‖pᵢ − π(K,d,R,t,Pᵢ)‖₂, RMSE = √(Σeᵢ² / N)
总 RMS 只能说明训练数据上的平均像素拟合,不能单独证明几何精度。应同时查看每幅图误差、误差在图像平面的空间分布、参数不确定度、去畸变后直线度以及留出图像的重投影误差。若某张图误差明显偏大,应检查角点错误、模糊、板面弯曲或错误尺寸,而不是立刻加入更多畸变参数。
指标
作用
建议做法
全局 RMS
快速比较同一数据集和同一模型
不作为唯一验收依据
per-view error
定位坏图和姿态弱约束
报告中保留每张图结果
留出重投影误差
检查泛化而非训练拟合
预留 20% 姿态不参与求解
直线度/边缘残差
检查畸变模型失配
观察画面边缘的直线与残差向量
参数稳定性
判断数据是否充分
重采样/Bootstrap,比较 K 与 d 的离散度
3 相机外参标定
3.1 外参的准确含义
外参描述参考物体或世界坐标系到相机坐标系的刚体变换。OpenCV solvePnP 的 rvec、tvec 使三维 objectPoints 从物体坐标系变换到相机坐标系,即 ᶜTₒ。它不是“相机在世界中的位姿” ^wT_c;后者需要求逆。
ᶜp = ^cT_w · 𝒘p, ^wT_c = (^cT_w)⁻¹, 相机中心 𝒘C = −Rᵀt
方向验证 把标定板原点 [0,0,0,1]ᵀ 乘以 solvePnP 输出的 ^cT_t,结果应位于相机前方且 Z>0;再把结果投影回图像检查像素位置。这比仅看 tvec 的正负号可靠。
3.2 PnP 方法选择
方法
点数/结构
特点
建议
SOLVEPNP_ITERATIVE
≥4(一般)
LM 迭代最小化重投影误差
默认稳健基线;可由初值继续优化
SOLVEPNP_EPNP
≥4
非迭代高效估计
点较多或需快速初值
SOLVEPNP_IPPE
平面点
输出平面位姿的两个候选
标定板/平面目标,需消除二义性
SOLVEPNP_IPPE_SQUARE
4 个方形点
专用方形标记顺序
AprilTag/ArUco 单标记,必须遵守点序
solvePnPRansac
带外点
RANSAC + PnP
存在误匹配时先剔除外点,再 refine
对于平面标定板,正视、距离很远或图像占比很小时,深度和平面法向更容易不稳定。应增加倾角与板面占比,并使用 reprojection、cheirality(点在相机前方)和相邻帧连续性选择正确解。
3.3 工作站固定外参
如果目标是求固定相机到机器人基座的变换 ^bT_c,单次 PnP 只有在标定板到基座 ^bT_t 已知时才能直接组成:
^bT_c = ^bT_t · (^cT_t)⁻¹
如果 ^bT_t 未知但标定板固定在末端、末端位姿可读取,则属于 Eye-to-Hand / Robot–World–Hand–Eye 问题,应使用多姿态联合求解,而不是把某一帧 PnP 结果当成基座外参。
4 手眼标定模型与方程
图 4 Eye-in-Hand 与 Eye-to-Hand 的安装方式、固定量和待求量
4.1 Eye-in-Hand:相机安装在末端
输入:每个姿态的机器人末端到基座 ^bT_g(i),以及标定板到相机 ^cT_t(i)。未知固定量为相机到末端 X=^gT_c;标定板到基座 W=^bT_t 在采集中保持不变。每帧满足:
^bT_g(i) · ^gT_c · ^cT_t(i) = ^bT_t
取两个姿态 i、j 并消去固定的 ^bT_t,可得到经典方程:
Aᵢⱼ X = X Bᵢⱼ, Aᵢⱼ = [^bT_g(j)]⁻¹^bT_g(i), Bᵢⱼ = ^cT_t(j)[^cT_t(i)]⁻¹
OpenCV calibrateHandEye 直接接收所有绝对位姿序列并在内部构造相对运动。参数名 R_gripper2base / t_gripper2base 表示 ^bT_g;R_target2cam / t_target2cam 表示 ^cT_t;输出 R_cam2gripper / t_cam2gripper 表示 ^gT_c。
4.2 Eye-to-Hand:相机固定在机器人外部
相机固定在工作站,标定板刚性安装在末端。未知固定量通常有两个:X=^bT_c(相机到基座)和 Z=^gT_t(标定板到末端)。每帧满足:
^bT_g(i) · ^gT_t = ^bT_c · ^cT_t(i)
这类问题可写成 AX=ZB 或等价的 Robot–World / Hand–Eye 联合标定。联合求解的优点是不用预先精确知道标定板相对法兰的安装位姿。若使用 calibrateHandEye 的“角色替换”技巧,可把每个 ^bT_g 求逆为 ^gT_b 并作为第一组输入,输出解释为 ^bT_c;但这一做法依赖严格的方向约定,必须用闭环验证。对需要正式交付的系统,更推荐显式使用联合方程或 cv.calibrateRobotWorldHandEye。
4.3 可观测性与退化
- 所有运动都是纯平移:无法充分约束手眼旋转。
- 所有旋转轴互相平行或运动近似共轴:某些自由度不可辨识或病态。
- 旋转角度过小:相对运动接近单位阵,噪声被放大。
- 平移变化极小:旋转与平移耦合方法中的平移估计不稳定。
- 标定板在图像中总是很小或近似正视:PnP 的法向与深度误差传递到手眼结果。
- 机器人位姿和图像不同步:算法会把时延误差错误地解释为手眼外参。
运动设计建议 采集 15–30 个高质量姿态,覆盖绕至少两个不平行轴的正负旋转;相邻姿态角度不宜全都过小。对高精度系统,应从更多候选姿态中选择条件数更好的子集,并做时间同步或静止触发。
5 主流手眼算法研究与选型
5.1 分离求解与同时求解
将 A、B、X 拆成旋转和平移后,AX=XB 产生 RₐRₓ=RₓRᵦ 和 (Rₐ−I)tₓ=Rₓtᵦ−tₐ。分离法先求 Rₓ,再线性求 tₓ;实现简单、易分析,但旋转误差会传播到平移。同时求解法用双四元数或扩展线性系统把旋转和平移共同表示,能保留刚体运动耦合,但对尺度归一化、噪声模型和退化运动也更敏感。
算法
类别
数学工具
优势
风险
OpenCV
Tsai–Lenz
分离
最小旋转参数/几何线性化
经典、快速、解释直观
大噪声或旋转分布差时平移受旋转误差影响
CALIB_HAND_EYE_TSAI
Park–Martin
分离
SO(3)/SE(3) 李群对数
闭式最小二乘、工程基线稳健
接近退化运动仍会病态
CALIB_HAND_EYE_PARK
Horaud
分离
单位四元数
旋转表示紧凑、传统替代方案
四元数符号与线性系统需一致处理
CALIB_HAND_EYE_HORAUD
Andreff
同时/在线
Kronecker/线性系统
可扩展在线标定,旋转平移联合
需要有信息量的平移;噪声与尺度会影响线性解
CALIB_HAND_EYE_ANDREFF
Daniilidis
同时
单位双四元数/螺旋运动
统一表达旋转和平移,SVD 求解
归一化、符号和数据几何不佳时可能不稳定
CALIB_HAND_EYE_DANIILIDIS
Shah / AX=ZB
联合
Kronecker + SVD
同时求 Robot–World 与 Hand–Eye 两个未知变换
输入方向更复杂,需要更严格闭环验证
calibrateRobotWorldHandEye
5.2 各方法要点
Tsai–Lenz:通过运动轴关系先计算旋转,再由线性方程计算平移。论文特别强调需要绕不同轴旋转才能唯一恢复三维关系。适合作为经典基线和教学推导。
Park–Martin:在欧氏群上利用矩阵对数把旋转共轭关系转成向量配准,再闭式求解。对多姿态最小二乘实现自然,建议作为第一工程基线。
Horaud:使用单位四元数建立旋转约束,并提供先旋转后平移与非线性联合优化框架。原研究的稳定性分析指出,同时优化在噪声下可更稳健。
Andreff:从 Kronecker 形式推导线性系统,并面向在线场景递增处理运动。适合持续标定研究,但静态工业部署仍应与离线方法交叉验证。
Daniilidis:用双四元数把刚体运动视为螺旋运动,同时估计旋转和平移。理论表达优雅,但并不意味着对任何采集数据都必然优于分离法。
Shah:面向 AX=YB / AX=ZB 联合问题,采用 Kronecker 积和 SVD 构造闭式解,适合 Eye-to-Hand 中两个固定变换均未知的场景。
5.3 工程选型策略
- 同一批清洗后的数据同时运行五种 calibrateHandEye 方法,所有方法使用完全相同的输入方向和单位。
- 先检查结果是否为合法 SE(3):RᵀR≈I、det(R)≈+1、平移量级合理。
- 在训练集上计算 pairwise AX−XB 残差和恒定链 ^bT_g·X·^cT_t 的离散度。
- 在未参与求解的留出姿态上计算同样指标,避免选择过拟合结果。
- 用独立空间基准做任务验证,例如机器人触碰已知球心、针尖对孔或抓取标定块。
- 若多方法差异远大于重复采集噪声,优先回查数据方向、同步与姿态几何,而不是“投票平均矩阵”。
6 标准工程实施流程
阶段
关键动作
阶段 A:定义坐标与接口
画出 {b},{g},{c},{t},记录每个 API 返回的变换方向、旋转表示、长度单位和时间戳含义。
阶段 B:冻结相机配置
固定分辨率、ROI、焦距、对焦、曝光策略和畸变模型;确认部署配置与标定配置完全一致。
阶段 C:内参标定
采集覆盖充分的图像,检测亚像素角点,求 K 与 d,剔除坏图并用留出集验证。
阶段 D:同步采集手眼数据
每个机器人姿态稳定后同时保存图像、机器人绝对位姿、时间戳、关节角和质量标志。
阶段 E:逐帧 PnP
对每张图求 ^cT_t,检查 Z>0、重投影误差、标记数量和候选解。
阶段 F:手眼求解
按安装形式组装输入,运行多个求解器;保存全部输出和参数版本。
阶段 G:闭环与独立验证
计算 SE(3) 闭环残差、留出姿态误差、重复采集稳定性和真实任务空间误差。
阶段 H:部署与漂移监控
固化矩阵方向、单位、序列化格式与版本;支架碰撞、对焦变化或维护后重新验证。
6.1 数据记录规范
字段
示例
说明
sample_id
0001
图像与机器人记录的唯一键
timestamp_cam / robot
ns 或 μs
同一时钟域优先;记录触发与采样时刻
image_path
images/0001.png
保存原始、无二次缩放图像
T_base_gripper
4×4, row-major
明确是 ^bT_g;单位 m
T_cam_target
4×4
由 PnP 得到 ^cT_t;单位 m
corner_count / reproj
48 / 0.21 px
逐帧视觉质量
robot_status
steady=true
是否停止、是否到位、是否报警
calib_version
camA_20260804_v1
内参、板尺寸、机器人 TCP 和代码版本
6.2 时间同步
动态采集时,图像与机器人位姿的时间偏差会形成与速度成比例的空间误差:位置误差约为 ‖v‖·Δt,姿态误差约为 ‖ω‖·Δt。最稳妥的离线方案是“机器人完全静止—等待机械振动衰减—触发相机—读取同一时刻位姿”;连续运动场景则要使用硬件触发、统一时钟或时间偏移联合估计。
δp ≈ v·Δt, δθ ≈ ω·Δt
7 实验设计与误差评价
7.1 数据集划分
建议至少进行三次独立采集,每次重新随机摆放姿态但不改变相机安装。每次数据按姿态分成 80% 求解集和 20% 留出集;不能把同一小范围连续帧随机拆到两边,否则留出集与训练集几何高度相似,会高估泛化能力。
数据子集
用途
最低内容
训练集
求 K/d 或手眼 X
丰富视角、覆盖完整工作空间
留出集
比较算法与超参数
包含新的姿态与距离
独立基准集
最终验收
不依赖同一标定板检测链的空间基准
重复采集集
稳定性/漂移
不同时间、相同硬件配置
7.2 手眼残差指标
Eᵢⱼ = (Aᵢⱼ X) · (X Bᵢⱼ)⁻¹
e_R = acos((tr(R_E)−1)/2), e_t = ‖t_E‖₂
另一个直观指标是计算每帧的闭环常量 Wᵢ=^bT_g(i)·X·^cT_t(i)。理想情况下所有 Wᵢ 相同。可用 SO(3) 旋转均值与平移均值作为中心,报告旋转 RMS/95 分位数和平移 RMS/95 分位数。Eye-to-Hand 则检查 GᵢZ 与 XCᵢ 两条链是否一致。
7.3 验收指标体系
层级
指标
说明
验收原则
像素层
重投影 RMS / P95
角点预测与观测差
与像素尺寸、成像噪声和任务要求绑定
几何层
闭环旋转/平移残差
AX=XB 或链式常量误差
训练与留出结果接近
稳定层
Bootstrap/重复标定离散度
参数对采样变化的敏感度
输出置信区间而非单个矩阵
任务层
抓取/触碰/测量误差
最终系统误差
作为最终放行依据
参考而非硬门槛 普通清晰工业图像的内参重投影 RMS 常希望低于约 0.3–0.5 px;高质量机器人系统的手眼重复误差可能希望达到 0.1–0.3°、0.5–2 mm 量级。但这些数字不能跨设备直接套用,最终阈值应从焦距、工作距离、机器人重复定位、标定板精度和任务公差反推。
7.4 不确定度与误差预算
误差源
典型机制
控制措施
相机检测
角点噪声、模糊、畸变模型误差
亚像素检测、提高板面占比、留出验证
标定板
尺寸误差、非平面、热胀冷缩
刚性加工板、尺寸溯源、平面度检查
机器人
绝对精度、重复定位、TCP/基座误差
区分重复精度与绝对精度;必要时机器人本体标定
安装结构
支架柔性、重力变形、碰撞漂移
刚性安装、姿态载荷评估、周期复核
同步
图像与位姿时间偏差
静止采集、硬件触发、统一时钟
算法
线性化、局部最优、离群值
多方法、鲁棒筛选、联合非线性优化
8 OpenCV / Python 实现模板
以下模板展示关键接口和变换方向。实际项目应补充相机驱动、机器人 CSV/JSON 解析、异常处理、时间同步和结果序列化。OpenCV 版本升级后应重新运行单元测试与已知数据回归测试。
代码 1 棋盘格内参标定骨架
import cv2 as cv
import glob, numpy as np
pattern = (9, 6) # 内角点列数、行数
square = 0.020 # 相邻角点距离,单位 m
objp = np.zeros((pattern[0] * pattern[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:pattern[0], 0:pattern[1]].T.reshape(-1, 2)
objp *= square
object_points, image_points = [], []
image_size = None
for path in sorted(glob.glob('intrinsic/*.png')):
gray = cv.imread(path, cv.IMREAD_GRAYSCALE)
if gray is None:
continue
image_size = gray.shape[::-1]
ok, corners = cv.findChessboardCornersSB(gray, pattern)
if not ok:
continue
object_points.append(objp.copy())
image_points.append(corners.astype(np.float32))
assert len(object_points) >= 12, '有效姿态过少或覆盖不足'
rms, K, dist, rvecs, tvecs = cv.calibrateCamera(
object_points, image_points, image_size, None, None)
print('RMS(px)=', rms)
print('K=\n', K)
print('dist=', dist.ravel())
代码 2 PnP 与齐次变换方向
def T_from_rvec_tvec(rvec, tvec):
R, _ = cv.Rodrigues(np.asarray(rvec, np.float64).reshape(3, 1))
T = np.eye(4)
T[:3, :3] = R
T[:3, 3] = np.asarray(tvec, np.float64).reshape(3)
return T
def invert_T(T):
R, t = T[:3, :3], T[:3, 3]
Ti = np.eye(4)
Ti[:3, :3] = R.T
Ti[:3, 3] = -R.T @ t
return Ti
# object_points 是标定板坐标,corners 是像素坐标
ok, rvec, tvec = cv.solvePnP(
object_points, corners, K, dist,
flags=cv.SOLVEPNP_ITERATIVE)
assert ok
T_cam_target = T_from_rvec_tvec(rvec, tvec) # ^cT_t
assert T_cam_target[2, 3] > 0 # 粗略 cheirality 检查
代码 3 Eye-in-Hand 多算法求解
METHODS = {
'TSAI': cv.CALIB_HAND_EYE_TSAI,
'PARK': cv.CALIB_HAND_EYE_PARK,
'HORAUD': cv.CALIB_HAND_EYE_HORAUD,
'ANDREFF': cv.CALIB_HAND_EYE_ANDREFF,
'DANIILIDIS': cv.CALIB_HAND_EYE_DANIILIDIS,
}
# T_base_gripper[i]:机器人 SDK 读取并确认方向为 ^bT_g
# T_cam_target[i]:PnP 输出并确认方向为 ^cT_t
R_g2b = [T[:3, :3] for T in T_base_gripper]
t_g2b = [T[:3, 3].reshape(3, 1) for T in T_base_gripper]
R_t2c = [T[:3, :3] for T in T_cam_target]
t_t2c = [T[:3, 3].reshape(3, 1) for T in T_cam_target]
solutions = {}
for name, method in METHODS.items():
R_c2g, t_c2g = cv.calibrateHandEye(
R_g2b, t_g2b, R_t2c, t_t2c, method=method)
X = np.eye(4) # X = ^gT_c
X[:3, :3] = R_c2g
X[:3, 3] = t_c2g.reshape(3)
solutions[name] = X
代码 4 闭环常量验证(示意)
def rotation_angle(R):
x = np.clip((np.trace(R) - 1.0) / 2.0, -1.0, 1.0)
return np.degrees(np.arccos(x))
def closure_stats(T_base_gripper, T_cam_target, X):
# 每帧 W_i = ^bT_g(i) · ^gT_c · ^cT_t(i),理想情况下 W_i 恒定
W = [G @ X @ C for G, C in zip(T_base_gripper, T_cam_target)]
t = np.stack([w[:3, 3] for w in W])
t_center = np.median(t, axis=0)
t_err = np.linalg.norm(t - t_center, axis=1)
# 简化旋转离散度:以第一帧为参考;正式项目可计算 SO(3) 均值
R0 = W[0][:3, :3]
r_err = np.array([rotation_angle(R0.T @ w[:3, :3]) for w in W])
return {
'translation_rms': np.sqrt(np.mean(t_err ** 2)),
'translation_p95': np.percentile(t_err, 95),
'rotation_rms_deg': np.sqrt(np.mean(r_err ** 2)),
'rotation_p95_deg': np.percentile(r_err, 95),
}
for name, X in solutions.items():
print(name, closure_stats(T_base_gripper, T_cam_target, X))
8.1 Eye-to-Hand 角色替换示例
代码 5 Eye-to-Hand 的方向变换与解释
# 目标固定在末端、相机固定在外部:
# P_i = (^bT_g(i))⁻¹ = ^gT_b;仍使用 C_i = ^cT_t(i)
T_gripper_base = [invert_T(T) for T in T_base_gripper]
R1 = [T[:3, :3] for T in T_gripper_base]
t1 = [T[:3, 3].reshape(3, 1) for T in T_gripper_base]
R_cam2base, t_cam2base = cv.calibrateHandEye(
R1, t1, R_t2c, t_t2c, method=cv.CALIB_HAND_EYE_PARK)
T_base_cam = np.eye(4) # 输出在此解释为 ^bT_c
T_base_cam[:3, :3] = R_cam2base
T_base_cam[:3, 3] = t_cam2base.reshape(3)
# 必须验证:^bT_g(i)·^gT_t ≈ ^bT_c·^cT_t(i)
# 若两个固定变换均未知且需正式交付,优先使用 AX=ZB 联合求解。
8.2 必须加入的单元测试
- invert_T(T) @ T 与 T @ invert_T(T) 均接近单位阵。
- 每个旋转矩阵满足 RᵀR≈I 且 det(R)≈1。
- 把标定板点经 ^cT_t 变换后 Z>0,并能重投影到原角点。
- 用人工构造的真值 X 生成无噪声 A、B,所有求解器应恢复真值。
- 平移单位从 mm 统一到 m 前后,旋转结果不变,平移按比例变化。
- 打乱一帧机器人位姿与图像的对应关系后,闭环误差应显著上升。
9 常见失败模式与排查
症状
可能原因
优先处理
结果方向完全相反
把 ^bT_g、^gT_b、^cT_t、^tT_c 混用
用一个已知点验证每个 API;统一 ^aT_b 记号;按公式求逆
平移大 1000 倍或小 1000 倍
标定板用 m、机器人用 mm
数据入库时统一 SI 单位并保存 unit 字段
重投影很好但抓取很差
内参只拟合训练图;手眼/机器人绝对精度/同步错误
做留出闭环和独立触碰实验,拆分误差预算
不同算法差异巨大
运动退化、坏帧、时间错配或方向错误
检查旋转轴分布、逐帧 PnP、时间戳和链式常量
平移漂移明显,旋转较稳定
旋转误差向平移传播;平移激励不足;板尺寸错误
增加大角度与不同距离;复核尺寸;联合优化
某些姿态 PnP 翻转
平面二义性、正视、小目标
使用 IPPE 候选、Z>0、连续性和重投影共同判定
内参每次变化很大
自动对焦/变焦、视角覆盖差、板不平
冻结光学设置;重新设计姿态;使用刚性板
边缘去畸变仍弯曲
模型不足或边缘约束不足
增加边缘样本;再评估 rational/fisheye 模型,避免盲目过拟合
结果随机器人姿态变化
支架柔性、法兰/TCP 定义变化、线缆拉扯
机械加固;检查负载与 TCP;分姿态验证
静态数据正常,运动中失败
时间同步/滚动快门
静止触发验证;硬件同步;建模时间偏移与滚动快门
9.1 排查顺序
- 先查方向和单位:这是“完全错误”的最高概率来源。
- 再查每帧视觉质量:角点、PnP、Z>0、重投影与异常值。
- 再查机器人数据:位姿定义、TCP、基座、欧拉角顺序、时间同步。
- 再查数据几何:旋转轴、角度幅度、平移、景深与图像覆盖。
- 最后才比较算法和优化器,并在独立验证集上做选择。
10 推荐实施方案
推荐基线 ChArUco 或高质量棋盘格 + Zhang 内参 + solvePnP/IPPE + Park 手眼基线 + 五算法横向比较 + 留出闭环 + 独立任务空间验收。Eye-to-Hand 两个固定变换均未知时采用 Shah/Robot–World–Hand–Eye 联合求解。
阶段
推荐配置
交付物
内参
20±10 张覆盖充分图像;固定分辨率与焦点;基础 5 参数模型起步
K、d、图像尺寸、RMS、per-view error、留出误差
手眼采集
15–30 个静止姿态;两个以上非平行旋转轴;图像与机器人同键同步
原图、^bT_g、^cT_t、时间戳、质量字段
求解
Park 为基线,同时运行其他四法;Eye-to-Hand 联合求解
所有候选 X/Z、算法与版本记录
验证
训练闭环 + 留出闭环 + 重复采集 + 独立触碰/抓取
R/t RMS、P95、任务误差、置信区间
部署
矩阵方向、单位、坐标轴、序列化与校验和固化
版本化 YAML/JSON、验收记录、复核周期
10.1 分阶段验收门
验收门
通过条件
Gate 1:内参
留出重投影误差与训练接近;边缘直线度正常;参数在重采样中稳定。
Gate 2:逐帧外参
所有有效帧 Z>0、PnP 误差受控、候选解无跳变。
Gate 3:手眼数学闭环
训练与留出 SE(3) 残差都达标,多算法结果合理一致。
Gate 4:系统任务
独立空间基准上的抓取/触碰/测量误差满足业务公差。
Gate 5:耐久性
跨时间、温度和典型机器人姿态的漂移受控。
10.2 进一步研究方向
- 把内参、畸变、逐帧目标位姿、手眼和机器人基座/世界外参放入同一 bundle adjustment 联合优化。
- 在 SE(3) 上使用稳健核函数与离群值模型,避免少数错误 PnP 主导解。
- 联合估计相机—机器人时间偏移,适配连续运动采集。
- 用概率模型传播角点、机器人位姿和板尺寸不确定度,输出手眼协方差。
- 针对鱼眼、滚动快门、远心镜头或折射介质建立专用成像模型。
- 用主动姿态规划最大化 Fisher 信息或降低条件数,减少采集数量。
附录 A 结果文件建议格式
建议的 YAML 语义:字段名直接编码变换方向,不使用含糊的 extrinsic
calibration:
version: camA_robot1_20260804_v1
units: meter
image_size: [1920, 1200]
camera_model: pinhole_brown_conrady
K: [[fx, 0, cx], [0, fy, cy], [0, 0, 1]]
distortion: [k1, k2, p1, p2, k3]
handeye:
configuration: eye_in_hand
transform: T_gripper_camera # ^gT_c:camera -> gripper
matrix: [[...], [...], [...], [0, 0, 0, 1]]
solver: PARK
validation:
reprojection_rms_px: ...
closure_rotation_p95_deg: ...
closure_translation_p95_m: ...
task_error_p95_m: ...
附录 B 现场采集检查表
- □ 相机分辨率、ROI、焦距、对焦和图像方向已冻结。
- □ 标定板型号、字典、角点数、方格/标签尺寸和单位已复核。
- □ 机器人基座、法兰、工具/TCP 定义已冻结并记录。
- □ 已用已知点验证机器人 API 位姿方向。
- □ 图像与机器人位姿使用同一 sample_id 和时间戳。
- □ 每次曝光时机器人静止,或系统具备可靠同步。
- □ 姿态覆盖至少两个不平行旋转轴、不同平移和不同距离。
- □ 标定板在所有有效帧中清晰、无遮挡或满足标签检测要求。
- □ 已保存原始图像,不经过缩放、裁剪或二次压缩。
- □ 已预留独立验证姿态和最终任务空间基准。
附录 C 关键公式速查
项目
公式
点坐标变换
^a p = ^aT_b · ^b p
变换复合
^aT_c = ^aT_b · ^bT_c
刚体变换求逆
R⁻¹=Rᵀ,t_inv=−Rᵀt
相机投影
s·p = K[R|t]P
Eye-in-Hand 单帧链
^bT_g · ^gT_c · ^cT_t = ^bT_t
Eye-in-Hand 相对运动
A X = X B
Eye-to-Hand 单帧链
^bT_g · ^gT_t = ^bT_c · ^cT_t
闭环残差
E=(AX)(XB)⁻¹
旋转测地角
θ=acos((tr(R)−1)/2)
参考文献与权威资料
[1] Z. Zhang. “A Flexible New Technique for Camera Calibration.” IEEE TPAMI, 22(11), 2000. DOI: 10.1109/34.888718. 访问来源
[2] R. Y. Tsai, R. K. Lenz. “A New Technique for Fully Autonomous and Efficient 3D Robotics Hand/Eye Calibration.” IEEE TRA, 5(3), 1989. DOI: 10.1109/70.34770. 访问来源
[3] F. C. Park, B. J. Martin. “Robot Sensor Calibration: Solving AX=XB on the Euclidean Group.” IEEE TRA, 10(5), 1994. DOI: 10.1109/70.326576. 访问来源
[4] R. Horaud, F. Dornaika. “Hand-Eye Calibration.” The International Journal of Robotics Research, 14(3), 1995. DOI: 10.1177/027836499501400301. 访问来源
[5] N. Andreff, R. Horaud, B. Espiau. “On-line Hand-Eye Calibration.” 2nd International Conference on 3-D Digital Imaging and Modeling, 1999. DOI: 10.1109/IM.1999.805374. 访问来源
[6] K. Daniilidis. “Hand-Eye Calibration Using Dual Quaternions.” The International Journal of Robotics Research, 18(3), 1999. DOI: 10.1177/02783649922066213. 访问来源
[7] M. Shah. “Solving the Robot-World/Hand-Eye Calibration Problem Using the Kronecker Product.” Journal of Mechanisms and Robotics, 5(3), 2013. 访问来源
[8] OpenCV 4.13.0. “Camera Calibration and 3D Reconstruction / calibrateHandEye.” 官方 API 文档。 访问来源
[9] OpenCV 4.13.0. “Perspective-n-Point (PnP) pose computation.” 官方教程。 访问来源
[10] OpenCV 4.13.0. “Camera Calibration.” 官方 Python 教程。 访问来源
[11] K. H. Strobl, G. Hirzinger. “Optimal Hand-Eye Calibration.” IEEE/RSJ IROS, 2006. 访问来源
[12] I. Enebuse et al. “Accuracy Evaluation of Hand-Eye Calibration Techniques for Vision-Guided Robots.” PLOS ONE, 2022. 访问来源
资料检索与接口核对日期:2026 年 8 月 4 日。报告中的工程阈值为经验性参考,正式验收应由任务公差和完整误差预算确定。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐







所有评论(0)