简介相机标定与定位是移动机器人视觉、无人机导航与增强现实系统的核心基础。该PDF文档系统梳理了从经典到现代的标定与定位算法涵盖Tsai三维靶标法、Zhang平面棋盘法、DLT直接线性变换及非线性优化校准并延伸至鱼眼、折反射等非传统相机模型的统一球面建模。内容兼顾理论推导与工程应用详细对比了P3P、EPnP等方法在不同场景下的性能表现配有大量数学公式和示意图便于读者透彻理解内参外参求解、畸变处理及位姿估计的完整链路。资源为单一PDF文件大小约3.44MB占用空间小适合从事机器人视觉、无人机导航、AR定位的研究人员和技术人员随时查阅。目前已有112人学习可作为相机标定与定位方向入门到进阶的实用参考。1. 为什么移动机器人的视觉算法绕不开相机标定先聊个大家都有体感的场景一台移动机器人装好双目相机代码里调用现成的目标检测模型明明检测框稳得很可一旦把像素坐标换算成机器人底盘的移动指令机械臂抓取位置就偏出一大截或者底盘靠近障碍物时总留出离谱的安全余量。这个问题的根子十有八九不是算法模型不行而是相机标定没做好。相机标定听起来是个纯数学活实际干起来却是个“脏活累活”。它要解决的事情很简单让机器人知道图像上的一个像素点对应到三维空间里的哪条射线、哪个方向。只有把这个对应关系搞准后面的视觉定位、视觉引导、SLAM建图才有基础。很多新手容易犯的错是把标定当成“跑一遍脚本出几个参数”的流程化操作忽略了采集数据质量、外参对齐、畸变模型选择这些真正影响精度的细节。这篇内容主要面向三类人刚接触移动机器人视觉的初学者、被标定结果折磨过的开发和调试工程师、以及准备把视觉定位方案落地到实际项目的同学。我会把相机标定和定位方法拆开讲再把它们串起来重点说明那些文档里不太会写、但实战中踩过的坑。1.1 相机标定到底在标什么先明确一个概念相机标定通常包含两部分内参标定和外参标定。内参描述的是相机本身的属性比如焦距、光心位置、畸变系数。内参决定了一个三维点投影到图像平面上时具体落在哪个像素。外参描述的是相机坐标系和机器人坐标系通常是底盘中心的 base_link 坐标系之间的旋转和平移关系外参决定了机器人怎么把“看到的目标”换算成“自己要去的位置”。拿人眼打个比方。内参好比是“近视度数”和“散光度数”度数不对看东西就是模糊的、变形的外参好比是“眼睛长在头部的哪个位置、朝向哪边”位置不对明明在正前方的物体手伸过去却偏了。移动机器人也是一样内参错了检测框和深度图容易出错外参错了目标定位会整体偏移偏偏这类问题在界面上还不容易看出来因为画面显示和检测结果看起来都是正常的。畸变模型同样值得关注。绝大多数工业相机和消费级相机都有一定的镜头畸变尤其是广角镜头边缘畸变非常明显。标定得到的就是一组畸变系数用于在算法层面把弯曲的图像“拉直”保证后续的像素坐标计算是准的。1.2 不标定就跑定位会翻什么车很多同学都会问我一个问题现在很多相机出厂自带标定参数或者直接用厂家SDK里的参数是不是就不用再标了我的回答通常是出厂参数可以做初值但最好不要当最终值尤其是用在移动机器人的定位任务上。原因有几个。第一相机镜头和机身之间是机械连接的运输震动、温度变化、安装时的受力都可能让镜头位置发生微小移动哪怕只有0.1毫米的偏差在10米的观测距离上也会被放大成数厘米的定位误差。第二你装在机器人上的位置和厂家标定时的工作台环境不一样比如加了红外滤光片、保护玻璃、镜头前的UV镜这些都会改变成像光路。第三外参完全取决于你的安装方式厂家不可能替你标好。不标定就上定位会出现很典型的现象Apriltag 码在近距离1~2米识别后测量距离大体靠谱一旦目标在5米开外测距结果就开始飘或者旋转机器人时同一个静止目标在坐标系里的位置会“漂移”转动回来又恢复这类问题基本都能追溯到内参不准。1.3 标定工具选型Matlab、OpenCV 还是 Kalibr工具选择没有绝对标准更多取决于使用场景。我自己的经验是分三档来看第一批是快速验证场景直接用 OpenCV 的calibrateCamera或stereoCalibrate配合棋盘格或者 AprilGrid 标定板。OpenCV 的优势是生态成熟、资料多、最容易上手而且可以直接对接 Python 或 C 代码适合在项目初期快速拿一套可用参数。第二批是精度要求较高的场景用 Matlab 的 Camera Calibrator 和 Stereo Camera Calibrator。Matlab 的优势在于交互体验好能直观看到每张图像的误差分布、剔除异常帧导出参数也很方便适合做一次性高精度标定。缺点是没法完全自动化融入产线流程。第三批是多相机系统或者视觉惯性系统用 Kalibr。Kalibr 是目前学术界和工业界都很常用的多相机标定工具支持相机内参、多相机外参、相机与IMU之间的外参和时间延迟估计。它在处理大视场角、鱼眼相机、多个相机联合标定时有明显优势输出结果也能直接对接 ROS 生态。顺带提醒一句ZED 2i 这类深度相机出厂时内置了标定参数SDK 里可以直接读取。但如果你发现深度图边缘有系统性误差或者彩色图和深度图对齐后有偏移不要只怀疑算法先做一次重标定问题往往会迎刃而解。2. 几种主流相机方案的标定实操与要点2.1 单目相机标定棋盘格、采集姿势与重投影误差单目标定是最基础的工作搞懂它之后双目和红外标定的思路都是延伸。整个流程看起来简单拍摄一组不同姿态下的棋盘格照片检测角点然后解算内参和畸变。但采集照片这个环节恰恰是很多人做的不到位的地方。实际操作时我一般会强调这么几点第一棋盘格的姿态要“够花”。要覆盖正视、左偏、右偏、上仰、下俯、旋转等多种角度同时保证在画面的中心、边缘、角落等不同区域都出现完整的棋盘格。为什么要这样因为标定算法需要从不同视角观察同一个平面才能解算出焦距和畸变系数。如果所有照片都拍得规规矩矩、正面直对相机算法会很“难受”解算结果也不稳定。第二照片数量一般在15~25张就够但前提是质量高。模糊的照片、反光的照片、棋盘格只露出一半的照片都要果断删掉。我有一个习惯每拍完一组就马上跑一次角点检测和重投影误差计算误差超过0.5像素的图片直接丢弃。这样做的好处是标定完最终结果基本都在0.2像素以内。第三标定板本身要平整。打印的棋盘格如果贴在弯曲的纸板或软塑料上角点检测是能检测出来但解算出的畸变参数会包含标定板本身的形变这会让整个标定结果失真。我建议用铝板或者亚克力板做底板表面贴哑光相纸这样反光也小。重投影误差是这个环节最需要关注的指标。简单说就是把棋盘格的已知三维角点按标定出的内外参重新投影到图像上算出来的像素坐标和实际检测到的角点坐标相差多少。误差小于0.1像素属于优秀小于0.5像素基本可用超过1像素就要重新标定。2.2 双目相机标定立体校正与基线精度双目相机标定比单目多了一个维度左右相机两两之间的外参也就是旋转矩阵 R 和平移向量 T其中平移向量的模长就是基线距离。基线的精度直接决定深度解算的精度这一点怎么强调都不过分。双目深度计算的原理是三角测量同一个空间点在左右图像上的成像位置不同这个位置差叫视差视差结合基线长度和焦距就能算出深度。如果基线长度标定错了1毫米在5米处的深度误差可能达到几十毫米而且是系统性的越远越明显。在用 OpenCV 做双目标定时stereoCalibrate会同时优化左右内参和两相机之间的外参。实际操作中我建议先分别对左右相机做单目标定再把单目标定结果作为初值传入双目标定做整体优化。这样做的好处是收敛更快也不容易陷入局部最优解。标定完成后还要做立体校正验证。简单讲立体校正就是通过左右画面的旋转和投影变换让左右图像的行对齐。判断方法是在左图上选一个特征点看它在右图上是否落在同一行。如果双目画面在视觉上有明显的上下错位深度图边缘容易出现不连贯的“撕裂感”。注意很多消费级双目相机出厂前在工厂里做过立体校正但如果外壳受过磕碰或者温度变化较大校正参数就可能失效。做一次自己的双目标定花一两个小时换来的定位稳定性提升是值得的。2.3 Ubuntu 24.04 ROS2 联合 ZED 2i 标定实录ZED 2i 在移动机器人圈子里用得不少因为它的 SDK 封装得比较完善深度图、IMU 数据、物体检测接口都现成。不过标定的流程和普通 USB 相机有些区别特别是走 ROS2 的话要注意数据流的获取方式。在 Ubuntu 24.04 下联合 ZED 2i 做标定我的实际流程大致是第一步安装并配置 ZED SDK确保ZED Explorer能正常打开相机彩色图和深度图都能显示。SDK 启动正常后再用ros2 launch zed_wrapper zed2i.launch.py启动 ROS2 节点确认能通过话题拿到图像数据。第二步准备标定板并采集数据。这里建议使用 ZED 自带的工具或者 ROS2 里的 image 话题订阅工具同时采集左右目图像。采集时要注意保持相机固定、移动标定板而不是拿着相机到处走动后者容易引入运动模糊。第三步标定解算。我常用的是基于 Kalibr 或 OpenCV 的流程把采集的左右目图像输进去得到左右内参、畸变系数、以及左右目外参。ZED 2i 还有一个特点是它的 SDK 支持直接读取出厂标定参数所以在自标定之前可以先导出出厂参数作为参考对比自标定结果的偏差。第四步把标定参数写回流程。在 ROS2 中使用 ZED 时参数通常以 YAML 文件的形式提供给 zed_wrapper 或者自己的视觉节点。需要注意图像分辨率、畸变模型是否和参数文件一致如果采集时用的是 1280x720 的尺寸标定结果也只适用于这个尺寸直接套用到 1920x1080 上会出问题。说说我踩过的一个坑一开始我以为 ZED 2i 的 IMU 和相机之间的外参也可以直接用出厂值结果做视觉惯性融合时发现角度飘得厉害。后来用 Kalibr 的 imu-camera 标定重新标了一遍才发现出厂值在安装后已经偏移了半度左右。半度看起来不大但积分几分钟后姿态就会明显漂移。2.4 红外相机标定与可见光有什么不同红外相机标定在巡检机器人、安防机器人、测温类项目里很常见。它的标定原理和可见光相机没有本质区别但有几个实际差异要特别处理。第一是分辨率低。很多热成像相机只有 640x512 甚至更低棋盘格角点检测的亚像素精度会明显不如可见光相机标定出的内参精度天然受限。解决办法是用分辨率高一点的红外机芯或者增大标定板尺寸尽量让角点覆盖更多像素。第二是视场角可能不同。红外镜头和可见光镜头往往不是同一个光学设计视场角、畸变特性都不一样所以不能复用可见光相机的内参。第三是标定板的材质。普通的纸质标定板在热成像下可能看不到图案因为纸在热红外下温度均匀没有对比度。常见的做法是用定制的高发射率/低发射率材料做成棋盘格图案或者用电加热板配合镂空模板。工业上也有直接买红外标定板的价格贵一些但省事很多。红外标定的畸变模型选择也要留意。大多数红外镜头视场角偏小用基础的径向切向畸变模型就够但如果用的是大视场角红外镜头可能需要换用鱼眼模型或者等距投影模型否则边缘畸变修正不干净。3. 移动机器人视觉定位方法的核心链路3.1 主流视觉定位思路横向对比标定只是手段定位才是目的。移动机器人视觉定位说到底就是回答一个问题目标在哪儿、我该往哪儿走。从实现思路上来分主流的方法大致有三类。第一类是地标定位也就是提前在环境中布置特征明显的标记比如 Apriltag、QR 码、反光标记点。机器人识别这些标记后结合已知的标记尺寸和相机内外参就能解算出标记相对于机器人的位姿。这类方法稳定、计算量小适合在仓库、工位、充电桩对接等结构化场景中做精定位。第二类是自然特征定位基于环境中已有的纹理特征比如 ORB、SIFT、SuperPoint 等特征点。机器人通过匹配当前图像和地图图像中的特征点算出自身位置。这类方法不用布设标记但在弱纹理环境、光照变化大的环境下容易失效。第三类是视觉里程计与 SLAM通过连续帧图像的相机运动估计来推算自身轨迹同时构建地图。视觉 SLAM 的优点是不依赖外部设施适合未知环境探索缺点是有累积漂移所以通常会和 IMU、轮式里程计做融合。三类方法不是互斥的实际项目中经常混用。举个例子机器人在通道里用视觉 SLAM 做全局定位到达充电桩附近后切换 Apriltag 做厘米级对接。前者的用途是“别走丢”后者的用途是“精确到位”各管一段。3.2 从像素到坐标内参外参如何串起定位链路定位的核心数学链路其实可以浓缩成一条线像素坐标 → 归一化相机坐标 → 相机系三维坐标 → 机器人系三维坐标 → 全局坐标。首先是像素坐标转归一化坐标。假设像素坐标是 (u, v)相机内参 fx、fy、cx、cy那么归一化坐标是x_n (u - cx) / fx y_n (v - cy) / fy这一步的实际含义是把像素位置投影到相机前方距离为1的归一化平面上消除相机内参带来的影响。如果做了畸变修正这里用的 (u, v) 应该已经是去畸变后的像素坐标。然后是单目情况下的“深度未知”问题。一个像素点对应的是相机前方的一条射线无法唯一确定三维位置。所以单目定位通常要依赖已知尺寸的物体比如 Apriltag、已知高度的地面平面、或者多帧之间的运动估计来恢复尺度。双目相机通过视差直接计算深度就不存在尺度不确定的问题。假设已经知道了深度 Z那么相机坐标系下的三维坐标就是X_c x_n * Z Y_c y_n * Z Z_c Z最后一步是通过相机到机器人的外参旋转 R、平移 T把坐标转换到机器人坐标系P_r R * P_c T这里面最容易出错的地方是坐标系的定义约定。不同 SDK、不同工具导出的 R 和 T 所对应的坐标系定义可能不一样比如是“相机系到机器人系”还是“机器人系到相机系”方向搞反了定位结果会整体镜像或者偏移。建议在接入代码前先用一个已知距离和方位的静态目标做一次坐标变换验证。3.3 视觉引导定位算法的落地流程视觉引导定位在移动机器人上最典型的应用是“识别目标 → 计算相对位姿 → 运动到位”。我以抓取场景为例说一下完整流程。第一步目标检测。这一步可以用传统的颜色阈值、轮廓提取也可以用深度学习的 YOLO 系列模型。检测的目的是在图像上框出目标区域。第二步目标姿态解算。如果目标是平面标记可以直接用 PnP 方法通过至少4个已知三维点和对应像素点解算位姿。如果目标是任意物体就需要从深度图获取目标区域的三维点云再做点云配准或质心估计。第三步可靠性验证。在实际项目里我会加一个验证步骤把解算出的目标三维位置投影回图像看是否和检测框重合。这一步看着多余但能有效剔除误检和深度异常值。第四步运动控制。把机器人坐标系下的目标位置发送给底盘控制器或机械臂控制器通常还会结合避障和路径规划模块。整个过程如果视觉反馈是闭环的就形成视觉伺服。这套流程里标定质量对前两步影响最大。内参不准导致像素反投影方向偏移外参不准导致坐标变换整体偏转基线不准导致深度全场缩放。所以定位精度不够的时候先回查标定再去调算法参数这个顺序才是高效的排查路径。4. 标定精度如何影响定位误差4.1 重投影误差的由来与判定标准重投影误差我前面提过概念这里展开说说它为什么会直接影响定位精度。标定其实就是求解一组参数使得所有角点的投影误差总和最小。重投影误差反映的是“模型和测量之间的拟合程度”它对定位的影响主要体现为内参误差会让反投影射线方向产生角度偏差这个角度偏差在远距离上会被放大成位置偏差。举个例子说明放大效应。假设图像上的角点检测误差为 0.5 像素镜头焦距是 600 像素那么在 1 米距离处反投影的位置误差大约为 0.5 / 600 * 1000 ≈ 0.83 毫米这个量级可以接受。但如果观测距离变成 10 米位置误差就变成 8.3 毫米而且这是理想情况下的下限。实际上内参误差、畸变残差会叠加10 米处差个 3~5 厘米也属于常见现象。所以在做高精度定位项目时我会把重投影误差目标定在 0.15 像素以内宁可多采集一些数据、多尝试几次也不接受“差不多能用”的标定结果。标定这种事前期多花一小时后期能少调一星期的参数。4.2 双目基线与时间同步深度精度背后的两个隐形变量双目相机的深度精度除了内参外还受两个因素影响很大基线精度和时间同步。基线也就是左右相机光心之间的距离。基线的绝对精度直接关系到深度解算的比例因子。假如真实基线是 120 毫米标定出来是 121 毫米这个 1 毫米误差会变成约 0.8% 的系统性深度误差在 5 米深度处就有约 40 毫米的误差并且整个画面的深度值都偏大或偏小属于一眼就能看出来的问题。时间同步则是很多开发者的盲区。左右目图像必须在同一时刻采集才能进行视差计算。如果左右图像存在几毫秒的时间差在静态场景中问题不大但机器人一旦运动起来运动目标或者机器人自身旋转时左右图像对应的是不同时刻的场景视差就会出错深度图边缘会出现明显的“条纹”或者“空洞”。ZED 2i 这类相机在硬件层面做了同步属于天生解决了一部分问题。但如果你用的是两个独立 USB 相机拼装的双目系统就要格外注意时间同步建议使用硬件触发或至少做软件时间戳对齐。4.3 实战中三类“标定没问题但定位不准”的翻车现场第一类近处准、远处偏。表现为机器人近距离抓取没问题但远距离导航、避障时目标位置总偏。常见原因是畸变校正不彻底画面边缘区域还有残余畸变远处目标恰好落在边缘附近。排查方法是看目标在画面不同位置时解算出的距离是否一致。第二类目标位置在左右方向上有系统性偏移。这种往往是外参的平移分量标定不准或者相机安装位置和标定时的假设位置不一致。比如换过一次相机支架但代码里的外参还是老参数。第三类定位结果随机跳变同一位置前后两次解算结果相差很大。这种情况常见于深度图噪声大、目标点云提取不稳定或者 PnP 求解时匹配到了错误特征点。处理思路是增加 RANSAC 迭代次数、限制解算结果的置信范围、对时间序列做滤波。5. 常见问题与排查技巧速查5.1 标定板拍了很多张却总是失败现象是 OpenCV 或 Matlab 老是检测不到角点或者检测到但图片被自动丢弃。常见原因有三个图像模糊导致角点定位不准、强反光导致棋盘格图案不清晰、棋盘格的部分区域超出画面。我的建议是采集时把相机固定住移动标定板每拍一张就在屏幕上放大看一遍角点检测结果。不要追求数量模糊的照片再多也没用。另外标定板尽量在光照均匀的环境下拍摄避免顶灯直射产生反光。5.2 标定结果和出厂参数差很多如果自标定出的 fx、fy 和出厂参数差了好几十个像素先别急着怀疑标定流程。检查一下有没有在相机镜头前加装保护玻璃或滤光片这些光学元件会改变等效焦距。再检查标定板本身是否平整不平整的标定板会显著影响焦距估计。还有采集的图像尺寸和出厂参数的标定尺寸是否一致。5.3 定位结果漂移和跳变怎么追定位结果短时间内的漂移优先怀疑深度源和时间同步问题。定位结果整体偏移优先怀疑外参。定位结果只有特定角度偏移优先怀疑畸变参数边缘残差。追查思路是控制变量先固定机器人位置和姿态观察静止目标的定位输出再让机器人平移、旋转逐步定位问题环节。5.4 问题排查速查表现象可能原因检查/解决办法远处定位不准畸变残余、内参不准重新严格标定重投影误差控制在0.15像素内目标位置整体偏移外参标定不准确重新标定相机到机器人外参验证坐标系方向深度值系统性偏大/偏小双目基线不准重新做双目标定核对基线长度深度图边缘出现条纹时间不同步检查硬件触发/时间戳对齐或更换为硬件同步相机定位结果随机跳变深度噪声大、匹配误检增加RANSAC迭代、深度滤波、时间序列平滑画面边缘明显畸变畸变模型不匹配尝试鱼眼/等距投影等更复杂模型最后再分享一个小技巧标定完不要只看数字指标一定要做“端到端验证”。拿一个已知实际距离的目标放在多个不同距离、不同朝向的位置用你最终的定位流程去解算对比误差。数字上再好看的标定最终都要落在“机器人在现场能不能干对活”这个唯一标准上。我个人的习惯是在每次项目验收前都会把这一套验证流程跑一遍哪怕只是一台车的标定也绝不跳过。本文还有配套的精品资源点击获取