资讯动态

相机标定与手眼标定全解析:从像素到三维坐标的完整链路

发布时间:2026/10/19 3:17:39 来源:尧图企业网站定制
1. 从像素到物理世界相机标定到底在解决什么问题做过视觉项目的人多半遇到过这种场景摄像头拍到了一张图你能准确说出某个特征点在图像里的像素坐标是第几行第几列但一旦有人问你“这个点在真实世界里离镜头多远、在什么方位”你就卡住了。相机标定要干的事就是在这两个坐标系之间架一座桥让像素坐标能换算成真实的三维空间坐标。我最早接触这个概念是在一个机械臂抓取的小项目里。当时用了一个普通的工业相机标定前抓取成功率大概只有六成标定之后直接拉到九成以上。差别在哪标定前系统只知道“目标在图像中间偏左”标定后系统知道“目标在相机坐标系下X0.23米、Y-0.05米、Z0.87米”。这个差距就是标定的价值。相机标定本质上是在求解一组参数这组参数描述了相机内部的成像特性内参和相机相对于某个世界坐标系的位置姿态外参。内参决定了三维空间中的点投影到图像平面上的方式外参决定了相机在世界坐标系中的摆放位置和朝向。两者合在一起才能完成从三维世界到二维图像、再从二维图像反推三维世界的完整映射。适合看这篇内容的人包括做机器人视觉引导的工程师、搞三维重建的开发者、做AR/VR定位的技术人员以及任何需要从单目或双目图像中获取空间信息的从业者。即便你之前没接触过标定只要了解基本的矩阵运算和坐标系概念下面的内容应该能帮你把整个流程跑通。2. 核心原理拆解四个坐标系与两次坐标变换2.1 四个坐标系的层级关系要理解标定先得把四个坐标系的关系理清楚。这四个坐标系从宏观到微观依次是世界坐标系、相机坐标系、图像物理坐标系、图像像素坐标系。世界坐标系是你自己定义的一个参考系可以放在任何地方比如放在标定板的第一个角点上也可以放在机械臂的基座中心。相机坐标系以相机光心为原点Z轴沿光轴方向指向拍摄场景X轴和Y轴分别平行于图像平面的水平和垂直方向。图像物理坐标系在成像平面上原点在光轴与成像平面的交点单位是毫米。图像像素坐标系也在成像平面上但原点在图像左上角单位是像素。从世界坐标系到相机坐标系是刚体变换用旋转矩阵R和平移向量t描述。从相机坐标系到图像物理坐标系是透视投影用焦距f描述。从图像物理坐标系到图像像素坐标系是缩放和平移用像素当量dx、dy和主点坐标u0、v0描述。2.2 内参矩阵的构成逻辑把上面后两步变换合并就得到了内参矩阵K。这个3x3的矩阵长这样K [[fx, 0, u0], [ 0, fy, v0], [ 0, 0, 1]]其中fx f/dxfy f/dy分别表示x和y方向上的等效焦距单位是像素。u0和v0是主点坐标理论上在图像中心附近但实际由于装配误差会有偏移。这里有个容易踩的坑很多人以为fx和fy一定相等实际上由于像素可能不是正方形、镜头可能有非对称畸变两者往往有细微差异。我在一个项目里遇到过fx和fy差了将近8个像素的情况如果强行设成相等重投影误差会明显变大。2.3 畸变模型为什么不可忽略理想的小孔成像模型假设光线沿直线传播但实际镜头尤其是广角镜头会产生畸变。主要分两类径向畸变和切向畸变。径向畸变让直线在图像边缘变弯表现为桶形畸变或枕形畸变。切向畸变则是因为镜头和成像平面不完全平行导致的。标定时通常用k1、k2、k3描述径向畸变用p1、p2描述切向畸变。注意如果你的应用场景只在图像中心区域工作畸变可能不明显可以不校正。但只要涉及图像边缘的测量畸变校正就是必须的。我见过一个测量项目因为忽略了畸变边缘区域的测量误差达到了3毫米以上。3. 标定实操全流程从准备到验证3.1 标定板的选择与制作标定板是标定的基准它的精度直接决定了标定结果的精度。常见的有棋盘格标定板和圆点标定板两种。棋盘格标定板的优势是角点检测算法成熟、亚像素精度高OpenCV对它的支持也最好。圆点标定板的优势是对模糊和光照变化更鲁棒但圆心提取的精度通常略低于棋盘格角点。我一般推荐用棋盘格具体参数选择上格子数量建议在6x9到10x7之间太少约束不够太多检测容易出错。格子物理尺寸根据你的工作距离来定工作距离近就用小格子比如20毫米工作距离远就用大格子比如50毫米甚至100毫米。制作标定板时打印精度很关键。普通打印机打出来的棋盘格边缘会有毛刺角点位置会有偏差。如果条件允许建议用激光打印或者找专业厂家制作陶瓷或玻璃基底的标定板。我试过用普通A4纸打印的标定板标定重投影误差在0.5像素左右换成专业标定板后降到了0.15像素。3.2 拍摄采集的实操要点拍摄标定图像是整个流程中最需要耐心的环节。核心原则是让标定板在图像中覆盖尽可能多的位置和角度。具体操作上我会这样安排拍摄标定板在图像中心、左上、右上、左下、右下各拍一张确保覆盖整个视场改变标定板的倾斜角度前后左右各倾斜20到45度每个角度拍2到3张改变标定板与相机的距离从最近工作距离到最远工作距离均匀分布总共拍摄15到30张太少约束不足太多计算量大且收益递减提示拍摄时标定板必须完整出现在图像中不能有遮挡。同时要保证标定板平面不要过度曝光或欠曝光角点对比度要清晰。有个细节很多人忽略拍摄过程中相机不能动标定板可以动或者标定板固定相机从不同角度拍。两种方式等价但前者更适合手持相机场景后者更适合相机固定的工业场景。3.3 角点检测与参数求解角点检测用OpenCV的findChessboardCorners函数检测到粗略角点后用cornerSubPix做亚像素优化。亚像素优化的窗口大小一般设成11x11迭代终止条件设成最大30次迭代或精度达到0.001。参数求解用calibrateCamera函数它内部用的是张正友标定法。这个方法的核心思想是利用标定板平面上的已知点与其图像投影点之间的对应关系先线性求解内参的初始值再用最大似然估计做非线性优化。调用时的关键参数包括ret, mtx, dist, rvecs, tvecs cv2.calibrateCamera( object_points, # 世界坐标系中的三维点 image_points, # 图像中的二维点 image_size, # 图像尺寸 None, # 初始内参矩阵None表示自动计算 None, # 初始畸变系数 flagscv2.CALIB_FIX_K3 # 根据实际情况选择是否固定某些参数 )flags的选择有讲究。如果标定图像数量少建议固定k3避免过拟合。如果图像数量充足且畸变明显可以让k3自由优化。3.4 重投影误差的解读与验证calibrateCamera返回的ret就是重投影误差单位是像素。这个值表示的是用标定得到的内参和外参把世界坐标系中的标定点重新投影到图像上与检测到的实际角点位置之间的平均距离。一般来说重投影误差在0.1到0.3像素之间算优秀0.3到0.5像素算合格超过0.5像素就需要检查问题。但要注意这个值受图像分辨率影响很大。高分辨率图像上0.5像素可能对应很小的物理误差低分辨率图像上0.3像素可能对应较大的物理误差。验证标定质量不能只看重投影误差。我通常会做两件事一是用标定参数去校正一张没参与标定的图像看畸变校正效果是否合理二是用标定参数做实际测量比如测量一个已知尺寸的物体看测量值与真实值的偏差。4. 手眼标定当相机遇上机械臂4.1 手眼标定的两种构型如果你的应用场景是机械臂抓取那光有相机标定还不够还需要手眼标定。手眼标定要解决的是相机坐标系和机械臂末端坐标系之间的变换关系。两种构型eye-in-hand和eye-to-hand。eye-in-hand是相机装在机械臂末端跟着机械臂一起动eye-to-hand是相机固定在外部机械臂在相机视野内运动。eye-in-hand的标定方程是AXXB其中A是机械臂末端的运动变换B是相机看到的标定板运动变换X是待求的相机到末端的变换。eye-to-hand的标定方程是AXZB其中X是末端到标定板的变换Z是相机到机械臂基座的变换。4.2 标定数据采集的注意事项手眼标定的数据采集比单纯相机标定更讲究。核心要求是机械臂的运动要尽可能覆盖工作空间且旋转运动要足够丰富。我一般会让机械臂走12到20个位姿每个位姿下拍摄一张标定板图像。位姿的选择上平移范围要覆盖整个工作空间旋转角度至少在正负30度范围内变化。如果旋转运动太少旋转矩阵的求解会不稳定。注意机械臂运动到位后要等完全停稳再拍照否则图像会有运动模糊角点检测精度会下降。我吃过这个亏有次赶时间没等停稳就拍结果重投影误差一直下不来排查了半天才发现是运动模糊导致的。4.3 标定结果的验证方法手眼标定做完后验证方法很直接让机械臂去抓一个已知位置的目标看抓取误差。如果误差在1到2毫米以内说明标定合格。如果误差大先检查相机标定的重投影误差再检查手眼标定的数据质量。另一个验证方法是用标定结果计算标定板在机械臂基座坐标系中的位置然后让机械臂末端去触碰标定板的几个角点看实际触碰位置和计算位置的偏差。5. 常见问题排查与避坑指南5.1 重投影误差偏大的排查思路重投影误差大是最常见的问题排查顺序建议如下排查项可能原因解决方法标定板图像质量模糊、过曝、欠曝重新拍摄保证角点清晰角点检测标定板部分遮挡或出界剔除不合格图像标定板平整度打印纸不平整使用硬质基底标定板畸变模型畸变严重但模型阶数不够增加k3或使用有理模型图像数量太少或位姿分布不均增加图像均匀分布位姿我遇到过一次重投影误差始终在0.8像素左右的情况换了标定板、重新拍了三次都没改善。后来发现是相机镜头没拧紧有轻微松动。所以排查时也要检查硬件安装是否牢固。5.2 标定结果不稳定的处理有时候标定结果会不稳定比如两次标定得到的内参差异较大。这通常是因为标定图像位姿分布不合理导致某些参数的可观测性差。解决办法是增加标定板的倾斜角度变化。如果所有图像中标定板都近似平行于图像平面那焦距和主点的求解会耦合在一起结果就不稳定。让标定板在正负45度范围内充分倾斜可以解耦这些参数。5.3 实际测量精度不达标的调优标定重投影误差很小但实际测量精度不达标这种情况也很常见。原因通常不在标定本身而在以下几个方面工作距离太远导致像素当量太大一个像素对应的物理尺寸太大标定时的距离与实际工作距离差异大外参外推误差大目标点提取精度不够比如用边缘检测提取的点精度低于标定板角点环境因素比如温度变化导致镜头焦距微变针对这些情况我的经验是尽量让标定时的距离和角度接近实际工作条件如果测量精度要求高考虑用更高分辨率的相机或者更长的焦距对于温度敏感的场景可能需要定期重新标定。6. 从标定到三维坐标计算的完整链路6.1 单目相机的三维坐标计算单目相机标定完成后从像素坐标反推三维坐标需要额外的约束。因为单张图像丢失了深度信息一个像素点对应的是空间中的一条射线而不是一个点。要确定三维坐标通常有两种方式一是已知目标在某个平面上的约束比如目标在传送带上传送带平面在世界坐标系中的方程已知二是已知目标的某些几何尺寸比如已知目标是一个直径10厘米的球。以平面约束为例计算过程是先用标定参数把像素坐标转换成相机坐标系下的归一化坐标再结合平面方程求解射线与平面的交点最后通过外参转换到世界坐标系。6.2 双目相机的三维坐标计算双目相机通过两个相机同时拍摄利用视差计算深度。标定需要分别标定左右相机再标定两者之间的相对位置关系。双目标定的关键是立体校正让左右图像的极线水平对齐。校正后同一个目标点在左右图像中的行坐标相同列坐标之差就是视差。深度Z f * B / d其中f是焦距B是基线距离d是视差。提示双目系统的精度很大程度上取决于基线距离。基线越长同样视差误差对应的深度误差越小。但基线太长会导致左右图像重叠区域减小所以需要根据工作距离折中。6.3 坐标转换的代码实现从像素坐标到世界坐标的完整转换用OpenCV实现大概是这样的import numpy as np import cv2 # 假设已经标定得到内参和畸变系数 # mtx, dist ... # 像素坐标 pixel_point np.array([[[u, v]]], dtypenp.float32) # 去畸变 undistorted cv2.undistortPoints(pixel_point, mtx, dist) # 归一化坐标 x_norm undistorted[0][0][0] y_norm undistorted[0][0][1] # 假设目标在Z0平面上世界坐标系 # 需要外参R, t # 构造射线方向 ray_dir np.array([x_norm, y_norm, 1.0]) ray_dir np.linalg.inv(mtx) np.array([u, v, 1.0]) # 结合平面方程求解 # ...实际使用时外参的获取方式取决于具体场景。如果是固定相机看固定平面外参可以通过标定板一次性确定。如果是相机运动外参需要实时估计。7. 标定精度的进阶优化策略7.1 多相机联合标定当系统中有多个相机时单独标定每个相机再标定它们之间的相对关系误差会累积。更好的做法是联合标定把所有相机的参数放在一个优化问题里同时求解。联合标定的优势是能利用所有相机之间的约束提高整体精度。实现上可以用ceres solver或者g2o这类优化库把重投影误差作为目标函数所有参数作为优化变量。7.2 在线标定与自标定传统标定需要专门的标定板和流程在一些应用场景中不方便。在线标定利用场景中的已知结构或者相机运动本身来估计参数不需要专门的标定物。自标定的核心思想是利用图像之间的对应点约束来求解内参。比如用SIFT或ORB提取特征点匹配后通过基础矩阵或单应矩阵约束来估计焦距和主点。但自标定的精度通常低于传统标定适合对精度要求不高的场景。7.3 温度与振动补偿在高精度工业场景中温度变化会导致镜头和相机结构微小变形振动会导致相机位置偏移。这些因素都会让标定参数失效。补偿方法包括在相机附近安装温度传感器建立温度与参数漂移的模型定期用标准件做校验发现偏差及时修正机械结构上做隔振设计减少振动影响。我在一个精密测量项目里的做法是每工作4小时用标准件校验一次如果偏差超过阈值就重新标定。虽然麻烦但保证了测量数据的可靠性。8. 我踩过的坑与实操心得说几个实际项目中踩过的坑希望能帮你省点时间。第一个坑是标定板打印精度。早期为了省事用普通打印机打棋盘格标定重投影误差一直在0.4像素左右下不来。后来借了一块专业标定板同样的流程跑下来直接降到0.12像素。标定板本身的精度是标定精度的上限这个钱不能省。第二个坑是拍摄时的光照。有次在车间现场标定顶部有强光直射标定板导致部分角点过曝检测出来的角点位置有偏移。后来用遮光板挡了一下问题解决。标定时的光照要均匀柔和避免直射光和反光。第三个坑是忽略畸变模型的适用性。有个项目用了鱼眼镜头但标定时用的是普通畸变模型结果边缘区域校正效果很差。鱼眼镜头需要用专门的鱼眼畸变模型OpenCV里有对应的fisheye模块。第四个坑是手眼标定时机械臂运动不够丰富。有次只让机械臂做了平移运动旋转角度很小结果标定出来的旋转矩阵误差很大。后来补做了几个大角度旋转的位姿精度才达标。最后分享一个实用技巧标定完成后把标定参数和当时的温度、工作距离、标定板型号都记录下来。下次如果发现精度下降可以快速判断是哪个因素变化导致的不用从头排查。这个习惯帮我节省了很多现场调试的时间。

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

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

免费获取报价 →
↑