首页 / 资讯中心 / 文章详情

相机内参标定核心:如何正确选择相机模型,避免重投影误差陷阱

相机内参标定核心:如何正确选择相机模型,避免重投影误差陷阱 ★ FEATURED ARTICLE
做相机标定这么多年我遇到过不少拿着标定板拍了几十张图、跑完流程却发现内参总是不对劲的工程师。有的人重投影误差看起来挺小可前端定位就是漂三维重建的效果也稀烂。说实话大部分情况下问题不是出在标定操作上而是你在动手之前根本没有想清楚一个问题该用哪种相机模型。这不是小题大做。相机模型决定了你把三维世界投影到二维图像这件事用什么样的数学公式去逼近。选错了模型后面所有环节——去畸变、特征匹配、三角化、BA优化——都会在错误的前提上叠加误差。这篇把相机内参标定的理论篇核心讲透尤其聚焦在模型选择的逻辑上。适合刚开始接触视觉SLAM、三维重建、机器人感知的工程师也适合那些已经标定过几次、但始终对结果存疑的开发者。1. 为什么标定前必须先整明白相机模型1.1 模型是标定的“答案形式”很多初学者会把相机内参标定理解成“算出一堆数”fx、fy、cx、cy加上几个畸变系数k1、k2、p1、p2然后写进配置文件里就完事了。这种理解不能说错但它忽略了最关键的一点这堆数本身是依附于特定公式结构的。同样的镜头你用针孔模型去拟合和用Kannala-Brandt鱼眼模型去拟合得到的内参数值可能差很多但各自都能在自己的公式体系下把畸变描述得“八九不离十”。真正决定标定精度的是模型结构和物理成像过程之间的匹配度。如果把镜头成像看作一个黑盒相机模型就是你对这个黑盒内部规律的假设。你假设它是线性的、对称的、低阶的那么你就用针孔加少量畸变参数去描述你假设它是高扭曲、大视场角的那你就得多项式、分段的去描述。标定的过程其实就是在这个假设框架内求解最优参数。假设错了参数再怎么优化也是错的。1.2 不同场景的模型偏好差异我见过有人在普通广角镜头上硬套鱼眼模型结果重投影误差反而飙升也见过有人用小孔成像模型去做车载环视边缘畸变校正得一塌糊涂。这两个例子恰恰说明了一件事相机模型不是越复杂越好而是越匹配越好。具体到应用场景比如室内视觉SLAM常用的普通镜头视场角在60到90度之间畸变相对温和用经典的针孔加径向切向畸变模型就够了。而运动相机、车载鱼眼镜头视场角动辄超过140度甚至190度针孔模型根本扛不住必须换用鱼眼模型族的各种变体。至于工业视觉里的一些远心镜头、线扫相机它们的成像模型又是另一套逻辑和普通透视相机完全不同。所以在标定之前你必须先回答一个问题我的相机属于哪一类我的应用需要哪种模型这决定了你后续所有工作的方向。2. 相机模型的核心从三维世界到像素坐标2.1 四个坐标系之间的流转关系相机模型本质上描述的是空间中的一个三维点如何一步步变成图像上的一个像素。这个过程中涉及四个坐标系世界坐标系、相机坐标系、图像物理坐标系、像素坐标系。这四个坐标系的关系可以这样理解世界坐标系是你自定义的参考系比如标定板所在的平面相机坐标系以光心为原点Z轴沿着光轴方向图像物理坐标系以光轴和成像平面的交点为原点单位是毫米像素坐标系以图像左上角为原点单位是像素。三维点先通过外参旋转矩阵和平移向量从世界系转到相机系再通过内参投影到图像平面最后加上畸变偏移得到最终的像素位置。实际编程时这四个坐标系的变换通常被合并成一个大矩阵来处理。但理解每一步的物理意义非常重要因为一旦标定结果异常你需要能够反推是哪一步出了问题。比如某个方向上的重建误差特别大往往是焦距估计不准图像中心区域的点对不准往往是主点偏移没收敛。2.2 针孔模型的数学表达与内参矩阵针孔模型是最基础、也是大多数人最先接触的相机模型。它的数学形式很简洁一个三维点(X, Y, Z)在相机坐标系下投影到图像平面上的坐标是(fX/Z, fY/Z)。这里f是焦距反映了镜头光学中心到成像平面的距离。加上主点偏移和像素缩放之后就得到了我们熟悉的内参矩阵K [fx 0 cx] [ 0 fy cy] [ 0 0 1]fx和fy分别代表x和y方向上的归一化焦距单位是像素。它们之间的比值表征了像素单元在x和y方向上的物理尺寸是否一致。cx和cy是主点坐标理论上应该在图像正中心但实际装配中会有几十个像素的偏移所以必须通过标定来确定。这里有个值得注意的点fx和fy的比值对很多标定算法来说是一个比较敏感的参数。如果标定图片数量不够、覆盖范围不好fx和fy可能会出现不合理的比值偏离。我早期踩过这个坑标定出的fx比fy大了将近3%后来查下来是图片里标定板大多只出现在画面的左侧区域导致的。所以看到内参矩阵里fx和fy差异异常大的时候不要急着用先想想采集数据是不是偏了。2.3 外参为什么也在标定流程里虽然标题是“内参标定”但实际标定过程中外参数是无法绕开的。因为单张标定图片只能提供标定板平面上的约束无法直接求解相机的内参。标定算法通常的做法是把每张图片的外参标定板相对相机的位姿作为待优化变量和内参一起迭代求解。这意味着标定板的位姿估计质量会直接影响内参的精度。如果标定板存在弯曲、不平整或者角点检测有系统性的偏差外参会先吸收这部分误差然后内参也会被带偏。这一点在理论篇里值得反复强调标定结果不是单纯由算法决定的数据质量的影响往往更大。3. 畸变模型针孔模型的必要补充3.1 径向畸变与切向畸变的来源完美的针孔模型是理想化的真实镜头由于加工和装配误差会产生各种畸变。畸变主要分两大类径向畸变和切向畸变。径向畸变源于镜头的曲面形状表现为直线在图像边缘处向内或向外弯曲。向内弯的叫桶形畸变常见于广角镜头向外弯的叫枕形畸变常见于长焦镜头。用泰勒多项式可以近似描述这种畸变dr k1r^3 k2r^5 k3*r^7这里的r是像素到主点的距离。k1、k2、k3就是径向畸变系数。切向畸变则源于镜头光学中心和成像平面不平行表现为图像在某些方向上被拉伸。用p1、p2两个参数描述。切向畸变的量级通常比径向畸变小一个数量级但如果装配工艺差也不可忽视。3.2 Plumb Bob模型和Rational模型怎么选OpenCV里最常见的畸变模型是Plumb Bob模型也就是大家熟悉的k1、k2、p1、p2、k3这五个参数。这个模型适合大多数普通镜头参数少优化稳定是默认首选。但对于畸变特别大的镜头比如一些廉价广角镜头k1、k2可能不足以描述畸变曲线。这时候OpenCV也提供Rational模型增加了k4、k5、k6三个高阶参数。参数多了拟合能力自然更强但也更容易过拟合。如果标定图片质量不高Rational模型可能把噪声也拟合进去结果重投影误差在标定数据上很小换到真实场景就露馅了。我的经验是先用Plumb Bob模型跑一遍如果重投影误差能控制在0.1像素以内就不要换模型。如果误差显著偏大再尝试Rational模型同时增加标定图片数量确保高阶参数被充分约束。畸变参数不是越多越好够用就行。3.3 一个容易被忽略的坑畸变参数和图像分辨率强相关同一台相机如果你用500万像素模式标定得到的内参在1200万像素模式下是不能直接用的。因为畸变系数和焦距都是以像素为单位的图像分辨率变了这些参数必须重新标定。这个坑我见不少人踩过。有次一个朋友做机器视觉项目标定的时候用的是预览分辨率跑应用的时候切成了高清分辨率结果定位精度差了老远。排查了半天才发现是内参和分辨率不匹配。所以标定时一定要先确定好应用时使用的图像分辨率并且保持两者一致。如果应用里不得不切换分辨率老老实实重新标定一次别偷懒。4. 广角和鱼眼镜头模型选择的分水岭4.1 视场角变大针孔模型为什么失效当视场角超过100度左右针孔模型的局限性就开始暴露了。原因在于针孔模型的投影公式是线性的透视投影它假定入射光线和成像点的关系可以用一个简单的比例来描述。但在大视场角下镜头的设计通常采用等距投影或其他非透视投影方式以保证边缘亮度均匀、畸变可控。如果强行用针孔模型去拟合大视场角镜头边缘区域的畸变残差会非常大。即使用高阶畸变参数去硬凑效果也很差。我试过用Rational模型去拟合一颗180度鱼眼镜头重投影误差始终在几个像素量级下不来后来换用Kannala-Brandt模型误差立刻降到0.5像素以内。4.2 不同鱼眼模型的数学差异鱼眼相机模型有很多种工程上常见的有等距投影模型、等立体角投影模型、正交投影模型以及后来广泛使用的Kannala-Brandt多项式模型。等距投影模型假设入射角theta和成像高度r成正比r f * theta。这是目前绝大多多数鱼眼镜头设计时遵循的准则也是很多标定工具默认使用的模型。FOV模型则用一个参数来描述畸变程度公式简洁特别适合嵌入式设备上做实时去畸变。Kannala-Brandt模型是这几年视觉SLAM领域的主流选择它用多项式把入射角映射到成像半径r f * (theta k1theta^3 k2theta^5 k3theta^7 k4theta^9)。这个模型的好处是兼容性好Orb-SLAM3、VINS-Fusion等主流开源框架都内置了对它的支持。而且它在描述鱼眼镜头畸变时精度和稳定性都相当不错。4.3 各模型标定公式与应用场景速查模型核心公式典型视场角标定工具复杂度适用场景针孔Plumb Bobu f*(x/z) 畸变修正 90度低普通镜头、SLAM、工业检测针孔Rational同上增加高阶畸变参数 120度中畸变较大的广角镜头FOV模型r f * theta单参数100-150度低实时性要求高的嵌入式设备Kannala-Brandtr f * poly(theta)100-190度中鱼眼SLAM、三维重建等距投影基本模型r f * theta100-190度低自制标定工具、鱼眼图像校正从标定工程的角度来说如果只是做相机标定和去畸变等距投影模型就够用如果要让标定结果直接接入SLAM系统选Kannala-Brandt会更省事因为主流的视觉SLAM框架都支持直接读取这种模型的参数。5. 工程视角下的模型选择决策标准5.1 从后端优化框架的角度反推模型很多工程师做标定的时候很纠结不知道该选哪种模型。我的建议是别闷头选先看看你后面的算法栈支持什么。如果你用的是VINS-Fusion做GPS融合定位它默认支持的就是针孔加Plumb Bob畸变以及Kannala-Brandt两种模型。你标定完的数据要能直接喂给这个框架模型类型就必须和框架匹配。ORB-SLAM3的情况类似它对鱼眼镜头只支持Kannala-Brandt模型对普通镜头支持针孔模型。如果你标定完用的是另一种模型的参数还得先做一次参数转换不仅麻烦转换过程也可能引入误差。所以“后端的兼容性”应当是模型选择的第一顺位约束条件。5.2 重投影误差阈值的界限标定完成后肉眼判断结果好不好的最简单指标就是重投影误差。普通镜头用针孔模型标定如果采集质量正常重投影误差一般能控制在0.05到0.15像素之间。超过0.3像素就需要警惕检查一下标定板是否平整、角点检测是否有问题、图像是否模糊。鱼眼镜头用Kannala-Brandt模型标定重投影误差会比普通镜头略大一些通常在0.1到0.5像素之间这也是正常的。如果鱼眼镜头的重投影误差能到0.1像素以下说明镜头质量很好数据采集也非常干净。要注意的是重投影误差只反映标定板和模型之间的拟合程度不代表相机在真实场景中的绝对精度。一个自洽性很好、但数据采集有偏的标定结果重投影误差也可能很低。所以不要唯误差论还要看看标定出的焦距和标称值是否接近主点是否偏离图像中心太多。5.3 退化风险与标定自由度模型参数越多需要的有效约束就越多。如果你只有十几张图片却用了k1到k6九个畸变参数大概率会出现过拟合或者参数相关性过强的情况。表现为主点和焦距的值在多次标定中漂移很大畸变参数内部相互补偿。这种退化问题在模型选择时就该提前避坑。我的习惯是初始标定尽量用参数少的模型确有必要再增加参数。参数少的模型即使精度稍低但鲁棒性强参数多的模型拟合能力强但需要高质量的数据来支撑。在数据量有限的情况下稳定比高精度更重要。6. 相机模型选择对数据采集方案的硬约束6.1 标定板的规格不能拍脑袋定标定板的规格包括格子大小、行列数、材质平整度都要根据相机模型和应用场景来定。普通镜头标定使用A4纸打印的棋盘格或者亚克力标定板就足够了。鱼眼相机的视场角大标定板需要离相机更近才能占据画面中的足够面积因此格子不宜过小否则近距离时角点会糊。精度要求高的场景建议使用陶瓷或者玻璃基材的高精度标定板热膨胀系数小平整度有保障。如果是室内环境温度变化大的车间不要用塑料基材的板子温度一变板子就弯了标定结果全废。6.2 采集姿态数量和位置分布标定图片的采集最常见的问题就是标定板总是集中在画面中央视角变化不大。这样的数据对求解焦距有帮助但对畸变参数几乎没什么约束力。你要让标定板出现在画面的边缘、角落以多种倾斜角度对着相机才能把畸变参数约束住。我常用的做法是“九宫格法”把画面横竖各分三份标定板依次出现在每个格子的中心区域每个区域拍3到5张并且姿态要有俯仰、偏航、翻滚的变化。这样一套拍下来20张左右的数据就足够稳定标定一套普通镜头内参了。鱼眼镜头的话还需要额外增加一些标定板贴近画面边缘的采集覆盖更大的畸变区域。6.3 采集环境的常见错误光照变化导致标定板反光、运动模糊导致角点检测偏移、标定板部分出画导致角点不完整这三类问题是导致标定失败的主要原因。特别是标定板反光会直接让角点检测出现系统性偏移比随机噪声更难排查。规避方法也很简单采集时用手动曝光或者固定曝光参数避免自动曝光导致画面亮度突变拍摄时尽量把相机固定住移动标定板而不是移动相机确保标定板完全在画面内不要有任何一条边被裁剪。这些细节听起来琐碎但每一条都对应着实际标定中实实在在的异常。7. 常见问题与排查技巧实录7.1 为什么重投影误差很低但重建效果很差这个问题在论坛里被问过无数次根源多半是过拟合。现象是标定数据上误差很小但一旦换到真实图像上去畸变后的图像依然有明显弯曲或者三维重建的点云出现系统性的弯曲变形。排查方法是把标定数据和测试数据分开。专门留出几张不参与标定的图片用来计算重投影误差和去畸变效果。如果测试误差明显高于训练误差说明模型或数据出了问题。另一种典型的过拟合是畸变参数过大比如k1绝对值超过1这往往意味着模型选错了或者数据中有严重的坏点。7.2 多相机标定时内参不一致怎么看做双目或者多目系统时有人会发现同一型号的两个相机标定出的焦距差了不少。这未必是标定错了。镜头模组的个体差异、安装时的受力不均、sensor贴装的位置偏差都会导致内参不完全一致。所以双目标定的第一步永远是分别对每个相机独立标定内参得到各自准确的参数后再进行双目标定求外参。如果两个同型号相机的焦距差异超过3%就要警惕了。这时候检查一下是不是某个相机的自动对焦没有关闭。相机内参标定的前提是焦距固定任何自动对焦、光学变焦功能都必须在标定前锁定否则焦距一变内参全部作废。这也是工业相机标定比手机相机标定容易得多的原因之一。7.3 一次标定和多次标定的结果应该取哪组有人喜欢连续标定三次然后取平均值。这么做的意义不大。如果三次标定结果非常接近说明系统很稳定取哪组都对如果三次结果差异显著说明数据采集或标定板质量存在系统性问题取平均值只会掩盖问题。更靠谱的做法是每次标定保存完整的标定报告包括重投影误差、每张图片的位姿、内参矩阵。如果两次标定的焦距差异超过1%、主点偏移差异超过5个像素就说明数据有问题需要重新采集。标定这件事数据的可重复性比单次的精度更重要。8. 模型选择之外标定流程里最容易被忽视的细节8.1 初始化值该怎么给标定算法通常需要给定初始值包括焦距和主点的初始猜测。对于普通镜头fx、fy的初始值可以设为图像宽度量级比如1280x720的图像fx初始值给1000左右比较合理cx给图像宽度的一半cy给图像高度的一半。畸变参数初始值全部设为0这样算法在迭代过程中从“无畸变”的假设开始逐步修正。初始化值给得离谱算法仍然可能收敛但很可能收敛到局部最优解。尤其是畸变参数如果初始值确实与实际值相差太大优化的收敛路径就会走向奇怪的位置。实际操作中如果发现标定结果与常识相差过大可以先检查初始化值是否合理再考虑是不是模型直接选错了。8.2 标定结果的鲁棒性验证标定完以后不要急着写进配置就完事。做一次简单的验证把标定板放到画面正中央正面正对相机在图像上找几个已知格点根据标定结果计算这些点的三维坐标和距离和标定板的实际格距对比。误差在1%以内基本可以放心。更严谨的做法是用一份独立采集的测试视频跑一遍去畸变观察画面边缘的直线是否拉直了。如果边缘的直线还有明显弯曲大概率是畸变模型参数不准或者模型选择有误。这种验证不花什么时间但能筛掉大部分标定问题。8.3 参数同步与工程交付最后一步往往被忽略就是内参参数在工程团队内部的传递。相机内参不是标定完就一劳永逸的镜头松动、跌落磕碰、温度漂移都可能导致内参变化。交付时除了参数文件还需要附带标定时间、图像分辨率、标定工具版本、采集环境说明方便后续排查问题。我所在的团队在交付标定结果时都会生成一个标准化的标定报告包含重投影误差散点图、每张图片的角点残差分布、标定板位姿可视化。这样如果在集成阶段发现视觉定位有问题其他人可以拿着报告快速判断是标定本身的问题还是后续算法使用的问题。在相机内参标定这个方向上模型选择永远是排在第一位的决策。先搞清楚你的镜头属于哪一类、数据要喂给什么框架、精度要求是什么水平再决定用针孔、多项式畸变还是鱼眼模型。模型选对了标定就是锦上添花模型选错了后面再努力也是缘木求鱼。希望这篇理论梳理能帮你在拿到标定板之前先把最关键的工作做完。
阅读完成 · 觉得有帮助?
咨询建站