资讯详情

相机模型核心解析:从针孔相机到K[R|t]的完整投影链路

📅 2026/10/25 10:21:38 | 华诺云谱 👁 阅读
相机模型核心解析:从针孔相机到K[R|t]的完整投影链路
一个做计算成像的朋友跟我说过一句话我一直记着所有相机的数学起点都是那个不起眼的小孔。不管你现在用的是手机、单反、工业相机还是车载摄像头你看到的每一张照片、每一个像素追根溯源都能回到针孔相机模型。这一讲我围绕K [R | t]这条核心主线把针孔相机、内参外参、景深和卷帘快门这四块内容串起来讲清楚。搞懂了这些你再去读任何跟三维重建、视觉SLAM、计算摄影有关的论文都会顺很多。1. 针孔相机一切相机模型的起点1.1 为什么针孔是“理想的相机”针孔相机的结构极其简单一个不透光的盒子一侧开一个小孔光线只能穿过这个小孔在对侧的底片上形成倒立的像。正因为只有通过小孔的光线能进入每个三维物点都对应像平面上的一个确定位置不存在镜头的复杂折射也不存在畸变。换句话说针孔成像在几何上是完美的中心投影这就是它成为一切相机模型起点的原因。我在实际项目里遇到那种对三维坐标系转换特别头疼的新人都会先让他忘掉镜头和CMOS只留一个盒子、一个小孔。为什么因为把镜头拿掉之后成像关系就只剩一个最简单的相似三角形。设相机坐标系下三维点坐标为(Xc, Yc, Zc)针孔在原点成像平面在Z f处像点坐标(x, y)就是x f * Xc / Zc y f * Yc / Zc这个公式我建议你亲手推一遍推完你对焦距、光轴、主点这些概念的理解会完全不一样。很多教材直接给你一个矩阵但你不知道每一行、每一列是怎么来的后面做相机标定、做双目重建的时候就很容易出错。1.2 从针孔到真实镜头有哪些差异真实的相机当然不会只靠一个小孔成像因为小孔进光量太少曝光时间必须拉长拍出来的东西又暗又糊。所以实际镜头用一组透镜代替小孔把光线汇聚起来进光量大幅提升。但透镜也有问题它有一定厚度、有一定折射特性边缘部分还会产生畸变。这里的核心近似是透镜组可以看作一个“等效针孔”所有光线经过透镜后等效于穿过一个叫做光心的点光轴与像平面交点附近的位置就是等效针孔位置。真实镜头和理想针孔的差异集中在几个地方主点不一定在图像正中心焦距可能不是单一的x和y方向的像素尺寸可能不一致镜头边缘有径向畸变和切向畸变。这些差异如果不管直接用理想针孔公式去还原三维信息误差会非常大尤其是在广角镜头和鱼眼镜头上。所以工程上先要用“针孔模型”去描述几何关系再用“畸变模型”去补偿镜头偏差这两件事是配套的。2. 内参矩阵K三维世界如何“落入”像素平面2.1 K矩阵里每一格的含义内参矩阵K是一个 3×3 上三角矩阵通常写成K [fx s cx 0 fy cy 0 0 1 ]每个元素都不是凭空来的。fx和fy是焦距在像素坐标系下的表达单位不是毫米而是像素。cx、cy是主点的像素坐标也就是光轴与成像平面交点的像素位置。s是倾斜因子用来描述像素坐标系两条轴不完全垂直的情况现代相机里它通常非常接近0很多算法直接忽略它。我经常被问为什么焦距不直接给一个毫米值非要整出fx f / dx这种东西因为工程最终要的是像素坐标而像素尺寸本身是物理尺寸除以感光元件分辨率换算出来的。f是物理焦距dx是每个像素在x方向的物理宽度fx f / dx就把物理焦距换算成了以“像素宽度”为单位的数值。这一步换算如果你漏了后面所有涉及像素大小和实际距离的换算都会出错。2.2 像素坐标系与成像平面坐标系的换算逻辑内参的关键作用是把相机坐标系里的三维点先投影到成像平面物理坐标再转成像素坐标。物理成像坐标(x, y)到像素坐标(u, v)的换算关系是u fx * x cx v fy * y cy这就是为什么 K 矩阵要把fx、fy放在左上角把cx、cy放在第三列。你从公式里能直接看出像素坐标不是从图像中心开始算的而是从图像左上角开始算的所以主点偏移(cx, cy)才必须被加回去。如果搞反了这个关系三维点在图像上的投影位置就会整体平移标定结果对不上重建出来全是错的。内参矩阵还有一个细节我特别想提醒K矩阵描述的是“相机坐标系到像素坐标系”的映射它只跟相机本身的物理属性有关跟相机放在哪、朝向哪没有任何关系。所以同一个相机无论你把它装在哪台机器人上、摆在哪个场地它的K是不变的。这也是为什么标定一次内参可以长期复用。2.3 畸变与内参标定的关系镜头畸变通常分为两类径向畸变和切向畸变。径向畸变是光线在透镜边缘发生更大偏折导致的表现为画面边缘的直线变弯切向畸变是由透镜安装时与成像面不完全平行导致的表现为点在切向方向发生偏移。工程上常用下式描述畸变模型x_distorted x * (1 k1*r^2 k2*r^4 k3*r^6) ...这里r是像点到主点的半径距离k1、k2、k3是径向畸变系数。实际标定棋盘格的时候用的就是这种模型标定完输出内参矩阵、畸变系数、旋转和平移外参。我见过很多项目主点标出来表面上看“还算准”但畸变系数不收敛最终三维重建偏差很大后来发现是标定板不平整、角点检测出错了。实操心得标定棋盘格时不要只拍正对着相机的图那样径向畸变的约束不够。要让棋盘格出现在画面的边缘和角落并且适当倾斜才能把畸变模型的参数“钉死”。我个人的习惯是拍20到30张覆盖九宫格各区域并且每次改变倾斜姿态和距离这样标定结果才稳定。3. 外参 [R | t]相机在世界中的“位置与朝向”3.1 世界坐标系与相机坐标系内参解决的是“相机坐标系下的三维点如何变成像素”但相机本身也有自己的位置和朝向。在实际项目中我们真正关心的是三维点在世界坐标系里的坐标比如激光雷达点云在车辆坐标系里的位置、机械臂末端在基地坐标系里的位置。要把世界坐标系的点转换到相机坐标系就需要外参。外参用[R | t]表示R是 3×3 的旋转矩阵t是 3×1 的平移向量。它们合起来是一个 3×4 的增广矩阵描述了从世界坐标系到相机坐标系的刚体变换。注意这个变换是刚体变换它不会改变物体大小只改变坐标系的旋转和平移。3.2 R 和 t 的物理意义R的每一列其实是世界坐标系的三个轴在相机坐标系下的方向向量。这句话反过来说也一样R的每一行是相机坐标系的三个轴在世界坐标系下的方向向量。初学的时候容易搞混我建议你用右手定则自己画一个小的坐标系旋转图把X轴转到Y轴方向观察旋转矩阵怎么变化一下就通了。t是世界坐标系原点在相机坐标系下的坐标。这里有个反直觉的点要特别注意外参描述的是“把世界坐标系变成相机坐标系”所以t是“世界原点在相机坐标系里的位置”而不是“相机在世界坐标系里的位置”。如果你从标定结果里读出一个t [1, 2, 3]那意味着世界原点位于相机坐标系的 (1, 2, 3) 处而相机在世界坐标系里的位置是-R^T * t。这个方向反了再多计算都是白搭。3.3 坐标变换的完整顺序从世界坐标系的点Pw到相机坐标系点Pc的完整变换如下Pc R * Pw t很多教材写成齐次形式[ Pc ] [ R t ] [ Pw ] [ 1 ] [ 0 1 ] [ 1 ]这个顺序不能乱。你先做旋转再做平移等价于把世界坐标系先转到与相机坐标系同方向再把原点挪过去。如果你先平移后旋转结果就完全不一样。项目中我常用的一个验证方法是把一个已知坐标的点比如棋盘格第一个角点的世界坐标代入手算一遍投影再用代码跑一遍看像素坐标是否一致。这一步花不了几分钟但能一次性排查掉坐标系方向搞反、矩阵转置这类低级错误。4. 完整投影 K [R | t]从三维点到像素的旅程4.1 齐次坐标与投影公式内参和外参合在一起的完整投影公式是z_c * [u, v, 1]^T K * [R | t] * [x_w, y_w, z_w, 1]^T这里的z_c是相机坐标系下的深度值它不是一个常量而是每个三维点自己的Zc。公式左边的[u, v, 1]^T是像素坐标的齐次形式右边的[x_w, y_w, z_w, 1]^T是世界坐标的齐次形式。你把这个矩阵展开会得到三个等式最后一个等式一定是 1 1而前两个等式里有z_c所以实际是用第三个等式的值去归一化前两个。我遇过不止一个人在这里懵掉为什么明明是三维点投影到二维公式里却要除以一个z_c因为针孔成像的本质就是相似三角形物距越远、像点越靠近光轴这个z_c就是那个“物距”在相机坐标系下的值。除以它是整个投影矩阵里最核心的非线性环节也是它保证了远处的物体看起来更小。4.2 计算流程拆解从世界坐标到像素坐标我给你一个可以直接照着算的流程已知世界坐标点Pw (Xw, Yw, Zw)用外参旋转平移Pc R * Pw t得到相机坐标(Xc, Yc, Zc)判断Zc 0如果Zc 0说明点在相机后方压根不该成像归一化坐标x Xc / Zcy Yc / Zc应用内参u fx * x cxv fy * y cy如果做畸变校正在第4步和第5步之间插入畸变修正模型。这个流程看起来很机械但每一步都对应了明确的物理意义。我在写代码时会把每一步都拆出来不直接调一个大封装函数这样出了问题能定位到是哪一步。4.3 反投影从像素到射线的意义正向投影是把三维点变成像素反过来单个像素能不能直接还原成唯一的三维点答案是否定的。一个像素只对应一条射线从相机光心出发、穿过该像素中心的三维射线。在这条射线上的任意深度点投影到图像上都是同一个像素。所以反投影得到的永远是一条射线不是点。这也是为什么单目相机无法直接测距必须借助双目、多视图或者运动恢复结构。你只有知道深度Zc才能把射线上的点“钉”在某个确定位置。这个概念在三维重建里特别重要凡是做深度估计、三角测量的人都必须把“像素对应射线”这个思维刻在脑子里。5. 景深为什么照片有的地方清楚有的地方模糊5.1 弥散圆与景深公式前面讲的针孔模型默认光线是理想汇聚的真实镜头可不是这样。真实镜头聚焦时只有位于对焦平面上的物体能清晰成像其他位置的物点成像后会在像平面上形成一个圆斑这个圆斑叫弥散圆。如果弥散圆直径小到人眼无法分辨看起来仍然是清晰的这个可接受的清晰范围就是景深。景深计算涉及一组公式工程上常用的简化版是这样的前景深 ( F * δ * L^2 ) / ( f^2 F * δ * L ) 后景深 ( F * δ * L^2 ) / ( f^2 - F * δ * L )其中F是光圈值δ是允许的弥散圆直径L是对焦距离f是镜头焦距。注意这里的F是 f-number数值越小光圈实际开口越大。我把这组公式自己推导过一遍核心思路就是对焦距离L处的物体正好聚焦在像平面物距稍微变小时像点落在像平面后方形成弥散圆再用相似三角形算出这个圆斑的直径让它小于允许的δ就能反推出前景深和后景深。5.2 光圈、焦距、物距如何影响景深很多摄影教程只说结论我想把背后的机制讲透。景深受三个因素影响光圈光圈越大f值越小进入镜头的锥形光束开口越大同样的离焦量产生的弥散圆直径就越大所以景深越浅。这就是为什么大光圈人像背景容易虚化。焦距焦距越长放大倍率越大微小的物距偏差在像平面上的偏移也被放大景深越浅。长焦镜头背景虚化能力比广角强本质原因在这里。物距对焦距离越近景深越浅。宏观上看公式里的分母中L^2的增速快过分子里的其他项微观上理解离得越近物体前后的微小距离变化在角度上的变化越明显。把这三个因素叠加你就知道想要“前景后景都清晰”的风景照应该用广角小光圈对焦在远处想要“突出主体”的人像应该用长焦大光圈离主体近一点。5.3 计算成像里的景深控制经验我在一个工业检测项目里要同时拍一个平面上的细小字符和它前方几毫米处的透明薄膜结果薄膜的纹理和字符叠在一起怎么都对不上焦。后来测量了景深范围发现按工作距离和光圈算出来的景深只有不到2毫米薄膜恰好超出范围。解决办法是缩小光圈到f/8同时把相机安装角度尽量垂直于被测平面景深一下就够用了。这里我想说的是景深不是摄影专属概念它在机器视觉里同样决定成败。另一个经验是生产线的光源如果用点光源物体会产生强烈阴影这虽然不是景深问题但会让自动对焦系统误判。所以我在做视觉检测方案时一般会建议使用低角度环形光或面光源减少对比度跳变让对焦和后续特征提取都更稳。6. 卷帘快门为什么高速运动经常“拍弯”6.1 全局快门与卷帘快门的本质区别CMOS 传感器的曝光方式主要分两类全局快门和卷帘快门。全局快门让所有像素在同一时刻开始曝光、同一时刻结束画面捕捉的是一个瞬间卷帘快门则是让每一行像素依次曝光通常是自上而下逐行进行的。为什么会有卷帘快门因为 CMOS 传感器面积大逐行读出可以把电路设计得更简单、成本更低手机和大多数民用相机都采用这种方式。卷帘快门的曝光不是瞬间完成的而是像窗帘一样扫过传感器的。这意味着画面最顶部一行和最底部一行实际记录的并不是同一个时间点的场景而是有一段时间差。这个时间差在静态场景下毫无影响但在快速运动场景下就会产生明显的几何失真。6.2 果冻效应的成因最典型的果冻效应就是拍高速转动的螺旋桨时叶片看起来不是平的而是弯的。原因是螺旋桨顶部先曝光底部后曝光等曝光轮到底部时叶片已经转到另一个位置了于是同一个螺旋桨在画面里被扭成了弧形。我还踩过一个更隐蔽的坑在移动平台上装相机边走边拍侧面建筑结果画面里竖着的电线杆歪了像是被风吹弯。这不是镜头畸变也不是相机没校准完全是因为车辆移动过程中卷帘快门逐行曝光每一行对应的车体位置不同导致竖直物体在图像里产生了倾斜。很多人一开始会误判成相机安装松动我建议你先看画面里是不是所有竖直边缘都朝同一个方向倾斜如果是大概率就是卷帘快门效应。6.3 工程中的规避手段应对卷帘快门有几个实用思路。首先是降低曝光时间曝光时间越短各行之间的时间差对整个场景位移的影响就越小但快门扫过整幅画面的总时间并没有变短多少。其次是调整拍摄方向让物体的主要运动方向与逐行扫描方向平行可以有效减少变形比如拍竖直运动物体时旋转相机90度让扫描方向变成水平。在视觉SLAM和三维重建项目中如果特征点会被卷帘快门效应污染我一般建议直接换全局快门相机尤其是在快速旋转或移动的场景。全局快门相机相对贵一些但省掉后续的几何校正。如果只能用卷帘快门相机就得在做运动补偿时加入IMU数据或者在算法里把每行的时间戳都建出来。7. 几个常见问题与排查心得7.1 相机标定总是不过大概率是这些原因我帮别人排查过很多标定失败问题频率最高的原因有三个。第一标定板尺寸输错了内角点距离填成了外角点距离误差直接翻倍。第二标定板反光和镜面反射导致角点检测失败我建议用哑光材质打印必要时用背光板增强对比度。第三图像数量太少或覆盖不均匀只在画面中心拍畸变参数根本约束不住多拍带边缘和倾斜的图结果会稳定很多。另一个常被忽略的细节是标定过程需要让棋盘格保持在一个固定平面内不要用手拿得弯弯曲曲板子不平整角点位置就会有毫米级的偏差。我在项目里习惯用平板贴纸或玻璃夹板标定精度肉眼可见地提升。7.2 景深没控制好画面“糊”的不是焦点怎么办有人问我为什么我光圈已经开到 f/8 了画面边缘还是糊这里有两种可能。一种是透镜在边缘的像场本身就差广角镜头最明显收小光圈能缓解但不能完全消除。另一种是镜头有场曲中心和边缘的最佳焦面不在同一个平面上这时你就算把光圈收到 f/16边缘也清晰不了。这类镜头问题在工业相机里非常常见选购时一定要看 MTF调制传递函数曲线而不能只看分辨率数值。机器视觉里还有一个经典误区为了景深拼命缩小光圈结果光照不够强行加大光源亮度又引入了严重反光。我的做法是先选合适的工作距离和焦距让景深计算出来刚好覆盖被测物体的高度差再用中等光圈配合均匀照明而不是一味追求小光圈。7.3 卷帘快门造成误差能不能后期救回来后期能不能救可以但要看场景。如果物体运动轨迹可以用匀速模型近似算法上可以对图像逐行进行反向位移补偿把每行像素按时间戳挪回同一个基准时刻。很多手持扫描仪就是这么做的。但如果物体做的是复杂非线性运动比如旋转搅拌、液体飞溅单帧图像就救不回来只能靠高速全局快门相机。有个更实用的经验是在拍摄前先判断一下有没有必要关心卷帘快门。静止场景、慢速场景拍出来的卷帘快门失真子像素级别都不到完全不用纠结一旦拍摄目标在画面中占据较大面积且移动速度很快就要警惕了。我在做运动捕捉项目时会先用手机拍一段快速挥手的视频观察手是不是有倾斜变形以此快速判断相机是否会被卷帘快门影响。最后分享一个让我印象很深的教训。有一次我在做多相机同步采集两台相机型号不同一台是全局快门一台是卷帘快门。外参标定和投影建模的时候直接用同一个相机模型去处理结果重建出来的三维点错位很严重。排查到最后才发现卷帘快门相机的每一行都有一个不同的采集时间而全局快门相机只有一个时间二者的时间基准根本对不上。后来我在搭建同步采集系统时一定会把快门类型写进相机参数清单里并给卷帘快门每一行加上独立时间戳。这个细节在所有文档里都不会写但实际项目里真的会坑人。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑