Part III · 第 10 章 相机与投影 · 10.1Part III · Ch. 10 Cameras & Projection · 10.1

针孔相机模型The Pinhole Camera

机器人最丰富的传感器是相机,而相机首先是一台把三维世界压成二维图像的机器:它丢掉了每个点的深度,只保留方向。这一节从一个小孔出发,用相似三角形推出 x = fX/Z,再用交互图弄清焦距、视场角、消失点、滑动变焦,以及为什么单张图像无法恢复深度。后面的标定、立体视觉、SLAM、NeRF 全都从这一个映射出发。 A robot's richest sensor is a camera, and a camera is first of all a machine that squashes the 3D world into a 2D image: it throws away the depth of every point and keeps only its direction. This lesson starts from a pinhole, derives x = fX/Z by similar triangles, and uses interactive figures to build intuition for focal length, field of view, vanishing points, the dolly zoom, and why one image cannot recover depth. Calibration, stereo, SLAM and NeRF all start from this one map.

约 32 分钟~32 min 前置:1.1 向量 · 1.3 矩阵即变换 · 3.3 雅可比 · 5.1 坐标系 · 7.3 正运动学Prereqs: 1.1 Vectors · 1.3 Matrices as Transformations · 3.3 The Jacobian · 5.1 Frames · 7.3 Forward Kinematics 6 个交互6 interactives

    1为什么机器人需要它Why robots need this

    相机便宜、轻、信息量巨大:一帧图像就有几十万到几百万个像素,而且它几乎是机器人唯一能"看见"颜色、纹理、文字和语义的传感器。抓取要知道杯子在哪里,导航要知道门在哪里,视觉伺服要把手爪对准螺丝孔,模仿学习的策略网络直接以图像为输入。但图像里没有一个数字写着"这个点离你 2.3 米"。要把像素变回三维世界,第一件事就是弄清楚:相机到底丢掉了什么,保留了什么。

    这是 Part III(3D 视觉与几何)的第一节,所以先说一下这一部分在讲什么。它只有一条主线:三维点 → 像素这个映射,以及怎样求它的逆。第 10 章(相机与投影)研究这个映射本身:针孔模型(本节)、齐次坐标(10.2)、内参外参与畸变(10.3)、标定(10.4)、平面到平面的单应(10.5)。第 11 章(多视图几何)问:有了两张以上的图像,怎样恢复深度和相机运动?对极几何、立体视觉、三角化、PnP、特征匹配与光束法平差。第 12 章(三维表示与配准)问:恢复出来的三维结构怎样存储、对齐、渲染?点云与 ICP、体素/网格/SDF、图形学管线、NeRF 与 3D Gaussian Splatting。每一章都是同一个映射的变奏,而它的第一个版本就是这一页。

    它和前面的内容有天然联系:像素坐标是一个向量(1.1 节),投影是一个"几乎线性"的映射(1.3 节),它的局部线性化就是雅可比(3.3 节),相机本身是一个坐标系(5.1 节)。装在机械臂末端的相机,位姿就是正运动学(7.3 节)再乘一个固定的手眼变换,没有任何新东西。

    Cameras are cheap, light and information-dense: one frame holds hundreds of thousands to millions of pixels, and a camera is nearly the only robot sensor that sees colour, texture, text and semantics. A grasp needs to know where the mug is, navigation where the door is, visual servoing how to line the gripper up with a screw hole, and an imitation-learning policy takes images straight in. Yet no number in an image says "this point is 2.3 m away". To turn pixels back into the 3D world, the first thing to understand is exactly what a camera throws away and what it keeps.

    This is the first lesson of Part III (3D Vision & Geometry), so a word on what the part is about. It has a single thread: the map from 3D points to pixels, and how to invert it. Chapter 10 (Cameras & Projection) studies the map itself: the pinhole model (this lesson), homogeneous coordinates (10.2), intrinsics, extrinsics and distortion (10.3), calibration (10.4), plane-to-plane homographies (10.5). Chapter 11 (Multi-View Geometry) asks: given two or more images, how do we recover depth and camera motion? Epipolar geometry, stereo, triangulation, PnP, feature matching and bundle adjustment. Chapter 12 (3D Representations & Registration) asks: how is the recovered structure stored, aligned and rendered? Point clouds and ICP, voxels/meshes/SDFs, the graphics pipeline, NeRF and 3D Gaussian Splatting. Every chapter is a variation on the same map, and its first version is this page.

    It connects naturally to what you know: a pixel coordinate is a vector (Lesson 1.1), projection is an "almost linear" map (Lesson 1.3), its local linearization is a Jacobian (Lesson 3.3), and a camera is a coordinate frame (Lesson 5.1). A camera mounted on an arm's wrist has a pose given by forward kinematics (Lesson 7.3) times one fixed hand-eye transform; nothing new there.

    2直觉:光线穿过一个小孔Intuition: light through a small hole

    最早的"相机"是一间暗室:在墙上开一个小孔,对面的墙上就出现一幅倒立的室外景象。原理只有一条:光沿直线传播。场景中每个点向四面八方发光,其中只有恰好穿过小孔的那一根射线能到达像平面,所以像平面上的每个点只"听到"场景里一个方向的光。

    下图是侧视图:针孔在原点,光轴指向右,物体是右边那根琥珀色的箭头(高 \(H\),距离针孔 \(Z\)),像平面在针孔后面 \(f\) 处(\(f\) 叫焦距,这里指"针孔到像平面的距离")。过针孔的那条射线把图分成两个相似三角形,一个以物体为边,一个以像为边,所以

    The first "camera" was a dark room: cut a small hole in one wall and an upside-down picture of the outdoors appears on the opposite wall. One principle explains it: light travels in straight lines. Every scene point sends light in all directions, but only the one ray that happens to pass through the hole reaches the image plane, so each point of the image plane "hears" light from just one direction of the scene.

    The figure is a side view: the pinhole is at the origin, the optical axis points right, the object is the amber arrow on the right (height \(H\), distance \(Z\) from the pinhole), and the image plane sits a distance \(f\) behind the pinhole (\(f\) is the focal length, here simply "pinhole to image plane"). The ray through the pinhole splits the picture into two similar triangles, one with the object as a side and one with the image, so

    $$ \frac{\hl{h}{h'}}{\hl{f}{f}} \;=\; -\,\frac{\hl{H}{H}}{\hl{Z}{Z}} \qquad\Longrightarrow\qquad |h'| = f\,\frac{H}{Z}. $$

    负号表示像是倒立的。计算机视觉里一般把像平面"搬"到针孔前面同样的距离 \(f\) 处(图中的虚线竖线,叫虚拟像平面):同一条射线与它相交在同一高度的镜像点,数值相同,像却是正的。以后我们永远用这个正立的约定。拖动箭头尖端,调焦距和孔径,注意三件事:像的大小 \(\propto f/Z\);孔变大时,一个场景点在像平面上被抹成一个光斑,直径 \(b = a(1+f/Z)\);而进光量 \(\propto a^2\)。孔也不能太小:太小则太暗,而且光的衍射会让光斑重新变大(最清晰的孔径大致与 \(\sqrt{f\lambda}\) 同量级,\(\lambda\) 是波长)。

    The minus sign says the image is upside down. Computer vision usually "moves" the image plane in front of the pinhole at the same distance \(f\) (the dashed vertical line, the virtual image plane): the same ray crosses it at the mirrored point, with the same numbers but an upright picture. We will always use this upright convention from now on. Drag the arrow tip, change the focal length and the aperture, and notice three things: the image size is \(\propto f/Z\); as the hole grows, one scene point is smeared into a blur disc of diameter \(b = a(1+f/Z)\); and the light collected is \(\propto a^2\). The hole cannot be too small either: it gets too dark, and diffraction makes the spot grow again (the sharpest aperture is of the order of \(\sqrt{f\lambda}\), with \(\lambda\) the wavelength).

    FIG 1针孔成像:相似三角形Image formation by a pinhole: similar triangles
    侧视图 · 光轴向右 · 高度向上SIDE VIEW · optical axis → · height ↑
    拖动琥珀色手柄同时改变物体高度 \(H\) 和距离 \(Z\)。两块青色三角形是相似三角形。紫色粗线是孔径有限时一个物点在像平面上的模糊斑(准确说是它的截面),琥珀色实线是物体倒立的像(切到"虚拟像平面"时,像是针孔前方正立的琥珀色虚线)。把鼠标悬停在上面公式里的 \(f, Z, H, h'\) 上,图中对应的长度会加粗。本图的"高度"向上为正;而相机坐标系的 \(y\) 轴向下,所以相机系的 \(Y = -H\)。 Drag the amber handle to change the object height \(H\) and distance \(Z\) together. The two cyan triangles are the similar triangles. The thick purple segment is the cross-section of the blur of one object point when the hole has a finite size; the solid amber segment is the object's inverted image (in "virtual plane" mode the image is the upright dashed amber segment in front of the pinhole). Hover \(f, Z, H, h'\) in the formula above and the matching length thickens. In this figure "height" is positive up, whereas the camera frame's \(y\) axis points down, so the camera-frame \(Y = -H\).
    试一试Try this
    • 让像和物体一样高(\(|h'| = H\),误差 4% 以内)。\(f\) 和 \(Z\) 之间是什么关系?Make the image exactly as tall as the object (\(|h'| = H\), within 4%). What relation between \(f\) and \(Z\) does that need?
    • 把孔径 \(a\) 开大,直到模糊斑比整个像还大。针孔为什么必须很小?可是太小又会怎样?Open the aperture \(a\) until the blur spot is bigger than the whole image. Why must a pinhole be tiny, and what goes wrong if it is too tiny?
    • 切换到"虚拟像平面",看像变成正立的。Switch to the "virtual plane" and watch the image turn upright.

    用透镜升级一下。小孔太暗,所以真实相机用透镜把穿过一个大孔径的整束光重新汇聚到一点。薄透镜公式 \(\tfrac1Z+\tfrac1{z_i}=\tfrac1F\)(\(F\) 是透镜焦距,\(z_i\) 是清晰成像的像距)说明:只有一个深度的平面能恰好聚焦,其他深度会模糊成直径 \(c\approx a\,|s-z_i|/z_i\) 的弥散圆(\(s\) 是传感器到透镜的距离),可接受的模糊范围就是景深;光圈数 \(N=F/a\) 越大(孔径越小)景深越深,越接近针孔。关键是:对"一个点落在哪个像素"这个几何问题,对焦清晰时透镜相机和针孔相机给出同一个答案,唯一的区别是 \(f\) 现在是"透镜到传感器的距离"(对远处物体就是 \(F\) 附近)。所以本课以及整个 Part III 都用针孔模型。

    Upgrading to a lens. A pinhole is dim, so real cameras use a lens to re-focus the whole cone of light through a large aperture back to a point. The thin-lens equation \(\tfrac1Z+\tfrac1{z_i}=\tfrac1F\) (\(F\) the lens focal length, \(z_i\) the in-focus image distance) says that only one depth plane is exactly in focus; other depths blur into a circle of diameter \(c\approx a\,|s-z_i|/z_i\) (\(s\) the sensor-to-lens distance), and the range of acceptable blur is the depth of field. A larger f-number \(N=F/a\) (smaller aperture) gives a deeper field, closer to a pinhole. The key point: for the geometric question "which pixel does this point land on", an in-focus lens camera gives the same answer as a pinhole camera; the only difference is that \(f\) is now the lens-to-sensor distance (about \(F\) for distant objects). That is why this lesson, and all of Part III, uses the pinhole model.

    核心洞见Key insight

    针孔相机保留方向,丢掉距离。每个像素对应空间里过针孔的一整条射线,射线上的所有点(近的小东西、远的大东西)成同一个像。从图像恢复三维,本质上就是在每条射线上把丢掉的那个数 \(Z\) 找回来。

    A pinhole camera keeps direction and discards distance. Each pixel corresponds to a whole ray through the pinhole, and every point on that ray (a small thing near, a big thing far) makes the same image. Recovering 3D from images is, at heart, finding the lost number \(Z\) on each ray.

    3动手玩:相机在世界里Play: a camera in the world

    现在把相机放进三维世界。左图是世界:地面网格(红线沿 \(x\),绿线沿 \(y\))、一个 1 m 的方盒(琥珀色)、三根竖直的杆(蓝色)和一台相机的视锥;相机自带的坐标轴是 OpenCV 光学坐标系:\(x_c\) 向右(红),\(y_c\) 向下(绿),\(z_c\) 向前(蓝)。右图是这台相机拍到的画面,像素坐标 \((u,v)\):\(u\) 向右,\(v\) 向下,原点在左上角。画面外的淡色线是"如果传感器更大会看到什么"。

    用滑块把相机绕场景转、拉远拉近、抬高降低,再调焦距。看三件事:平行线怎样汇聚到消失点(彩色圆圈,与世界轴同色;用同样方式画出的虚线是地平线);同一个方盒怎样随位置变大变小;以及改变焦距与移动相机有什么不同。

    Now put the camera into a 3D world. The left view is the world: a floor grid (red lines along \(x\), green along \(y\)), a 1 m box (amber), three vertical poles (blue) and a camera frustum; the camera's own axes are the OpenCV optical frame: \(x_c\) right (red), \(y_c\) down (green), \(z_c\) forward (blue). The right view is what this camera sees, in pixel coordinates \((u,v)\): \(u\) to the right, \(v\) down, origin at the top-left corner. The faint lines outside the frame show "what a bigger sensor would see".

    Use the sliders to orbit the camera around the scene, move it in and out, raise and lower it, and change the focal length. Watch three things: how parallel lines meet at vanishing points (coloured rings, matching the world axes; the dashed line through them is the horizon); how the same box grows and shrinks with position; and how changing the focal length differs from moving the camera.

    FIG 2相机在世界里,与它拍到的画面The camera in the world, and the image it takes
    世界 · 拖动旋转WORLD · drag to orbit
    图像 640×480 px · v 向下IMAGE 640×480 px · v points down
    相机的位置由绕场景中心的方位角、水平距离、高度确定,并始终看向场景中心("视点"滑块把中心沿 \(x\) 平移)。\(f\) 是以像素为单位的焦距,主点固定在图像中心 \((320,240)\)。红/绿/蓝圆圈是世界 \(x/y/z\) 方向的消失点 \(\mathbf v = K R_{cw}\mathbf d\)(它是方向 \(\mathbf d\) 的像,与相机位置无关,只与朝向有关);虚线是地平线 \(\mathbf l = K^{-\top}R_{cw}\mathbf e_z\),即地面无穷远线的像(它经过 \(x\)、\(y\) 消失点,其中一个在无穷远时也照样画得出)。公式行里是方盒中心 \(\mathbf X_c\) 的投影。 The camera position is set by an azimuth around the scene centre, a horizontal distance and a height, and it always looks at the scene centre (the "aim" slider shifts that centre along \(x\)). \(f\) is the focal length in pixels and the principal point is fixed at the image centre \((320,240)\). The red/green/blue rings are the vanishing points \(\mathbf v = K R_{cw}\mathbf d\) of the world \(x/y/z\) directions (the image of a direction \(\mathbf d\) depends only on orientation, not on position); the dashed line is the horizon \(\mathbf l = K^{-\top}R_{cw}\mathbf e_z\), the image of the ground's line at infinity (it passes through the \(x\) and \(y\) vanishing points and is drawn even when one of them is at infinity). The formula row shows the projection of the box centre \(\mathbf X_c\).
    试一试Try this
    • 让地面上的一族平行线汇聚到图像内部的一点(某个消失点落进画面)。提示:试试"沿着路看"。Make a family of parallel floor lines converge inside the image (a vanishing point lands in the frame). Hint: try "look down the road".
    • 让相机几乎垂直向下看:三根竖直的杆也开始汇聚(蓝色消失点进入画面)。为什么平视时它们是平行的?Make the camera look nearly straight down: the three vertical poles start converging too (the blue vanishing point enters the frame). Why were they parallel when looking level?
    • 让方盒占满画面(像高超过画面高度的 85%)。有几种办法?Make the box fill the frame (image height over 85% of the frame). How many ways are there?
    • 让方盒缩成一个小点(像高不到 40 px,仍然完整在相机前方)。Shrink the box to a speck (image height under 40 px, still fully in front of the camera).
    • 把视场角(FOV)调到 100° 以上:画面边缘的物体发生了什么?再用"远、长焦"预设对比。Push the field of view above 100°: what happens to objects near the frame edges? Then compare with the "far, tele" preset.
    核心洞见Key insight

    相机有两类旋钮:位置/朝向(外参,6 个自由度)决定"从哪里看",焦距(内参)决定"取多大一块视野放大到传感器上"。平行线在三维中永不相交,在图像中却相交于消失点:消失点只取决于方向与相机朝向,是一个在无穷远处的点的像,这正是下一节(10.2 射影几何)要处理的无穷远点。

    A camera has two kinds of knobs: position and orientation (the extrinsics, 6 degrees of freedom) decide "from where to look", and the focal length (an intrinsic) decides "how big a patch of the view is magnified onto the sensor". Parallel lines never meet in 3D but meet in the image at a vanishing point: it depends only on the direction and the camera orientation and is the image of a point at infinity, exactly what the next lesson (10.2, projective geometry) formalizes.

    4第二、第三视角:深度去哪了,透视由什么决定Second and third views: where did depth go, and what sets perspective

    深度丢失:一个像素就是一条射线Depth is lost: a pixel is a ray

    反过来问:已知一个像素,三维点在哪里?答案是一条射线:沿射线的每一点都投影到这个像素。下图(侧视图,相机在左边,像平面归一化到 \(f=1\),实际换算用 \(f=800\) px)里,琥珀色手柄在像平面上选像素,拖动射线上的点手柄改变深度,像始终不变。一个近处的小东西,一个远处的大东西,一个更远的巨人,它们的像完全相同,这就是单目的尺度歧义:玩具车模型和真车拍出来分不出来。

    怎么解决?再来一台相机。第二台相机的射线与第一条相交于一点,交点就是三维点(深度恢复,11.3 节)。打开"两台相机",第二台相机里同一个点的像素位置随深度变化,差值就是视差 \(d = f\,b/Z\)(\(b\) 是基线,这里为了画在侧视图里把基线画成竖直的;真实的立体相机是水平的)。

    Ask the reverse question: given a pixel, where is the 3D point? The answer is a ray: every point along it projects to that pixel. In the figure below (side view, camera on the left, image plane normalized to \(f=1\), pixel conversion with \(f=800\) px), the amber handle picks the pixel on the image plane and the point handle on the ray changes the depth while the image never changes. A small thing near, a larger thing farther, a giant even farther: their images are identical. This is the scale ambiguity of a single camera: a toy-car model and a real car look the same.

    The fix is a second camera. The second camera's ray meets the first at one point, and the intersection is the 3D point (depth recovery, Lesson 11.3). Turn on "two cameras": the pixel of the same point in camera 2 moves with depth, and the difference is the disparity \(d = f\,b/Z\) (\(b\) the baseline, drawn vertically so it fits in this side view; real stereo rigs are horizontal).

    FIG 3深度丢失:沿视线滑动Depth is lost: slide along the viewing ray
    侧视图 · 归一化像平面 f = 1SIDE VIEW · normalized image plane f = 1
    琥珀色粗线是高为 \(S\) 的竖直物体(底在光轴上),淡色的是深度减半/加倍、尺寸减半/加倍的"替身",三者在像平面上的像是同一段。红色虚线是视线延伸到相机后面的部分:那里的点(\(Z<0\))也落在同一个像素。右侧的第二行是 \(v\) 对 \((Y,Z)\) 的雅可比,它与射线方向的乘积为 0:射线正是投影的零空间。"两台相机"模式下,相机 2 的像平面上空心琥珀圈标出相机 1 看到该点的位置,紫色箭头 \(d\) 从它指向相机 2 实际看到的位置,长度就是视差。 The thick amber line is a vertical object of height \(S\) (base on the optical axis); the faded ones are stand-ins at half/double the depth with half/double the size, and all three have the same image on the image plane. The red dashed part is the viewing ray extended behind the camera: points there (\(Z<0\)) land on the same pixel too. The second line on the right is the Jacobian of \(v\) with respect to \((Y,Z)\); its product with the ray direction is zero: the ray is exactly the null space of the projection. In "two cameras" mode the hollow amber ring on camera 2's image plane marks where camera 1 saw the point, and the purple arrow \(d\) runs from it to where camera 2 actually sees it: its length is the disparity.
    • 沿射线把点的深度改变 2.6 倍以上,而像素一动不动。物体的真实高度 \(S\) 变化了多少?Slide the point's depth by a factor of 2.6 or more along the ray while the pixel stays put. How much did the true height \(S\) change?
    • 打开"两台相机",调节深度使视差正好是 100 px(±4)。反过来由视差算深度:\(Z = f b/d\)。Turn on "two cameras" and set the depth so the disparity is exactly 100 px (±4). Invert it to get depth: \(Z = f b/d\).

    透视强弱由相机位置决定:滑动变焦Perspective strength comes from position: the dolly zoom

    很多人以为"广角镜头让透视夸张,长焦镜头把背景压扁"。更准确的说法是:透视的强弱由相机的位置决定,焦距只决定取景范围。把相机从主体前退后的同时拉长焦距,让主体在画面里保持同样大(\(f/Z\) 不变),背景却会"涨"起来:这就是希区柯克《迷魂记》里的"滑动变焦"(dolly zoom,Vertigo effect)。道理很简单:主体深度 \(Z\)、背景深度 \(Z+D\),同样大小的东西在画面里的比是

    Many people believe "wide lenses exaggerate perspective, tele lenses flatten the background". More precisely, perspective strength is set by the camera's position, and the focal length only sets the framing. Back the camera away from the subject while lengthening the focal length so the subject keeps the same size in the frame (\(f/Z\) constant), and the background "swells": this is the dolly zoom (Vertigo effect) from Hitchcock's Vertigo. The reason is simple: with subject depth \(Z\) and background depth \(Z+D\), equal-size things appear in the frame in the ratio

    $$ \frac{s_{\text{bg}}}{s_{\text{subject}}} \;=\; \frac{f\,S/(Z+D)}{f\,S/Z} \;=\; \frac{Z}{Z+D}. $$

    这个比值只与 \(Z\) 和 \(D\) 有关,与 \(f\) 无关。\(Z\to\infty\) 时比值趋于 1(背景与主体一样大,画面"平",即长焦的压缩感);\(Z\) 小时背景被甩得很小(广角的"纵深感")。下图的左半是俯视图(相机在下,光轴向上,青色扇形是视场),右半是相机画面(主体是琥珀色的人,后面是 3 m 和 8 m 处的两排建筑)。选"锁定主体大小"后,拖动距离,焦距会自动跟着变。

    This ratio depends only on \(Z\) and \(D\), not on \(f\). As \(Z\to\infty\) it tends to 1 (the background is as big as the subject, a "flat" picture, the compression of a tele lens); for small \(Z\) the background is dwarfed (the "depth" of a wide lens). The left half of the figure below is a top view (camera at the bottom, optical axis up, cyan wedge = field of view) and the right half is the camera image (the amber figure is the subject, with two rows of buildings 3 m and 8 m behind). Choose "lock subject size" and drag the distance: the focal length follows automatically.

    FIG 4滑动变焦(Vertigo 效应)Dolly zoom (the Vertigo effect)
    俯视图 · 光轴向上TOP VIEW · optical axis ↑
    相机画面 640×480CAMERA IMAGE 640×480
    主体高 \(S=1.7\) m,相机离地 1.5 m;两排建筑在主体后 \(D=3\) m(紫)与 \(8\) m(蓝)。"自由"模式下 \(Z\) 与 \(f\) 各自独立;"锁定"模式保持当前的 \(f/Z\) 不变,主体在画面里的像高就不变。预设的三个按钮都使用锁定模式。 The subject has height \(S=1.7\) m and the camera is 1.5 m above the ground; two rows of buildings stand \(D=3\) m (purple) and \(8\) m (blue) behind the subject. In "free" mode \(Z\) and \(f\) are independent; "lock" keeps the current \(f/Z\) fixed, so the subject's image height does not change. The three preset buttons all use lock mode.
    • 打开"锁定主体大小",把相机距离改变 3 倍以上。主体不动,背景在"呼吸",同时视场角怎么变?Turn on "lock subject size" and change the camera distance by a factor of 3 or more. The subject stays put while the background "breathes"; how does the field of view change?
    • 让主体仍有 120 px 以上高,同时近处那排建筑的比值 \(Z/(Z+D)\) 达到 0.8:这就是长焦的"压扁"。Keep the subject at least 120 px tall while the near building row reaches \(Z/(Z+D)\ge\) 0.8: that is the tele "squash".
    • 反过来:主体仍有 120 px 以上高,视场角超过 110°:背景被甩得很远,边缘被拉伸。The other way round: keep the subject at least 120 px tall with a field of view above 110°: the background is pushed far away and the edges get stretched.

    很远时:弱透视,与投影的雅可比Far away: weak perspective, and the Jacobian of projection

    当物体的深度起伏 \(\Delta Z\) 远小于它到相机的平均距离 \(Z_0\),投影公式里的除数 \(Z\) 几乎是常数 \(Z_0\),投影就近似成一个线性映射:\(u\approx f X/Z_0 + c_x\),即弱透视(缩放的正交投影):把三维点丢掉 \(Z\),整体缩放 \(f/Z_0\)。下图把一个立方体放在深度 \(Z_0\),琥珀色是真实的透视投影,紫色虚线是弱透视(两者都用 \(Z_0/f\) 换回米,所以弱透视的立方体永远是同一个大小)。右图是最大偏差(占立方体边长的百分比)随 \(Z_0\) 的变化。

    弱透视的另一个说法是投影雅可比的第三列趋于 0。完整的像素 \(\mathbf u = (u,v)\) 对相机系三维点 \(\mathbf X=(X,Y,Z)\) 的雅可比是 \(2\times3\) 矩阵(推导见第 5 节):\(J = \tfrac1Z\begin{bmatrix}f_x&0&-f_xX/Z\\0&f_y&-f_yY/Z\end{bmatrix}\)。前两列是"横向移动 1 m,像素动 \(f/Z\) px",第三列 \(-f X/Z^2\) 是"靠近或远离时像素沿径向外扩",\(Z\) 大时可以忽略。它是 \(2\times3\),必有一维零空间,这一维就是视线方向 \(\mathbf X\) 本身(读数里验证 \(J\mathbf X=\mathbf 0\)):沿射线移动三维点,像素纹丝不动,与 FIG 3 完全吻合。这个雅可比在视觉伺服里叫"图像雅可比"(interaction matrix 的平移部分),在光束法平差(11.6 节)里则是每个重投影误差对点坐标的导数。

    When the depth relief \(\Delta Z\) of an object is much smaller than its mean distance \(Z_0\), the divisor \(Z\) in the projection formula is nearly the constant \(Z_0\) and projection becomes approximately linear: \(u\approx f X/Z_0 + c_x\), the weak-perspective model (scaled orthography): drop \(Z\) and scale everything by \(f/Z_0\). In the figure a cube sits at depth \(Z_0\); amber is the true perspective projection and the purple dashed cube is weak perspective (both are converted back to metres with \(Z_0/f\), so the weak-perspective cube always has the same size). The right panel plots the maximum deviation, as a percentage of the cube's edge, against \(Z_0\).

    Another way to say weak perspective: the third column of the projection Jacobian tends to 0. The full Jacobian of the pixel \(\mathbf u = (u,v)\) with respect to the camera-frame 3D point \(\mathbf X=(X,Y,Z)\) is a \(2\times3\) matrix (derived in Section 5): \(J = \tfrac1Z\begin{bmatrix}f_x&0&-f_xX/Z\\0&f_y&-f_yY/Z\end{bmatrix}\). The first two columns say "a sideways move of 1 m shifts the pixel by \(f/Z\) px", while the third, \(-f X/Z^2\), says "moving closer or farther pushes the pixel radially outward or inward" and is negligible for large \(Z\). Being \(2\times3\) it must have a one-dimensional null space, and that dimension is the viewing direction \(\mathbf X\) itself (the readout checks \(J\mathbf X=\mathbf 0\)): move the 3D point along the ray and the pixel does not budge, exactly as in FIG 3. In visual servoing this is the "image Jacobian" (the translational part of the interaction matrix), and in bundle adjustment (Lesson 11.6) it is the derivative of every reprojection error with respect to the point.

    FIG 5透视 → 弱透视,与投影雅可比Perspective → weak perspective, and the projection Jacobian
    立方体的像(按 Z₀/f 换回米)CUBE IMAGE (scaled back to m by Z₀/f)
    立方体边长 1 m,中心在相机系 \((0.4,\,0.15,\,Z_0)\),绕竖直轴转动的角度由"转动"滑块控制,并固定前倾 0.5 rad。偏差取八个顶点透视像与弱透视像之差的最大值。右图中的虚线是 5% 的水平线,竖直的琥珀线标出当前 \(Z_0\)。公式行用了立方体中心的雅可比(\(f = 800\) px),读数里把解析雅可比与有限差分比较,并验证零空间。 The cube has 1 m edges and its centre sits at \((0.4,\,0.15,\,Z_0)\) in the camera frame; the "spin" slider turns it about the vertical axis, with a fixed forward tilt of 0.5 rad. The deviation is the largest difference between the perspective and weak-perspective images of the eight vertices. In the right panel the dashed line is 5% and the vertical amber line marks the current \(Z_0\). The formula row uses the Jacobian at the cube centre (\(f = 800\) px); the readout compares the analytic Jacobian with a finite difference and verifies the null space.
    • 把立方体推到远处,让透视与弱透视的偏差小于 3%。此时雅可比第三列相对第一列有多大?Push the cube far away until perspective and weak perspective differ by less than 3%. How big is the third Jacobian column relative to the first?
    • 把立方体拉近,让偏差超过 25%:此时"缩放的正交投影"完全不可用了。Pull the cube close until the deviation exceeds 25%: "scaled orthography" is now useless.
    一个映射,三种看法One map, three views

    几何:像素 = 过针孔的一条射线(FIG 1、3),深度是射线上的位置。代数:\(u = f_xX/Z + c_x\),一个除以深度的非线性映射,下一节把它写成线性的齐次坐标形式。微分:投影的雅可比是 \(2\times3\),零空间是视线(FIG 5),对三维点位置的微小改变,像素只对垂直于视线的分量有反应。三种看法是同一件事:相机只保留方向。

    Geometry: a pixel is a ray through the pinhole (FIGs 1, 3) and depth is a position along it. Algebra: \(u = f_xX/Z + c_x\), a nonlinear map with a division by depth, which the next lesson rewrites linearly in homogeneous coordinates. Calculus: the projection Jacobian is \(2\times3\) with the viewing ray as its null space (FIG 5), so for a small change of the 3D point the pixel reacts only to the component perpendicular to the line of sight. The three views say the same thing: the camera keeps only direction.

    5再看数学The math

    提示:把鼠标悬停在公式中带底色的符号上,FIG 1 中对应的长度会加粗。Tip: hover the highlighted symbols in the formulas; the matching length in FIG 1 thickens.

    投影方程The projection equations

    取相机坐标系:原点在针孔,\(x\) 向右,\(y\) 向下,\(z\) 沿光轴向前(OpenCV 光学坐标系,Part III 一律使用)。点 \(\mathbf X=(X,Y,Z)\),\(Z>0\)。虚拟像平面 \(z=f\) 上的交点由相似三角形给出:

    Use the camera frame: origin at the pinhole, \(x\) right, \(y\) down, \(z\) forward along the optical axis (the OpenCV optical frame, used throughout Part III). A point \(\mathbf X=(X,Y,Z)\) with \(Z>0\) meets the virtual image plane \(z=f\) at a point given by similar triangles:

    $$ x = \hl{f}{f}\,\frac{X}{\hl{Z}{Z}},\qquad y = f\,\frac{Y}{Z}. $$

    把度量单位的像平面坐标 \((x,y)\) 换成像素:像素是边长为 \(p\)(像元尺寸)的小方块,原点在左上角,主点(光轴与图像的交点)在 \((c_x,c_y)\)。令 \(f_x=f_y=f/p\),即以像素为单位的焦距:

    To convert the metric image-plane coordinates \((x,y)\) to pixels: a pixel is a small square of side \(p\) (the pixel pitch), the origin is the top-left corner and the principal point (where the optical axis meets the image) is at \((c_x,c_y)\). Set \(f_x=f_y=f/p\), the focal length in pixels:

    $$ u = f_x\,\frac{X}{Z} + c_x,\qquad v = f_y\,\frac{Y}{Z} + c_y,\qquad f_x=f_y=\frac{f_{\text{mm}}}{p_{\text{mm}}}\ \text{(square pixels)}. $$

    例如 2.8 mm 的镜头、3 µm 的像元:\(f_x = 2.8/0.003\approx 933\) px;若图像宽 1280 px,水平视场角是 \(2\arctan\tfrac{1280/2}{933}\approx 68.9^\circ\)。一般地,宽 \(w\) 像素的传感器对应的水平视场角(FOV)是

    For example a 2.8 mm lens with 3 µm pixels gives \(f_x = 2.8/0.003\approx 933\) px; with a 1280 px wide image the horizontal field of view is \(2\arctan\tfrac{1280/2}{933}\approx 68.9^\circ\). In general a sensor \(w\) pixels wide has horizontal field of view (FOV)

    $$ \text{FOV}_h = 2\arctan\frac{w}{2 f_x} = 2\arctan\frac{w_{\text{mm}}}{2 f_{\text{mm}}}. $$

    注意是半角的正切再乘 2,而不是 \(w/f\) 的反正切。也要注意一个像素对应的视角约为 \(1/f_x\) rad,在距离 \(Z\) 处一个像素覆盖约 \(Z/f_x\) 米:933 px 的镜头在 5 m 处,每个像素约 5.4 mm。

    Note it is twice the arctangent of the half-width ratio, not the arctangent of \(w/f\). Also note one pixel subtends about \(1/f_x\) rad, so at distance \(Z\) a pixel covers about \(Z/f_x\) metres: with the 933 px lens at 5 m, about 5.4 mm per pixel.

    它不是线性的:齐次坐标的预告It is not linear: a preview of homogeneous coordinates

    把 \(u,v\) 写成矩阵形式,会发现差一点就是线性的:

    Write \(u,v\) in matrix form and you find it is almost linear:

    $$ Z\begin{bmatrix}u\\v\\1\end{bmatrix} = \underbrace{\begin{bmatrix}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{bmatrix}}_{K}\begin{bmatrix}X\\Y\\Z\end{bmatrix}\quad\Longleftrightarrow\quad \lambda\,\tilde{\mathbf u} = K\,\mathbf X_c,\ \ \lambda = Z. $$

    右边对 \(\mathbf X_c\) 是线性的,左边的 \(\tilde{\mathbf u}=(u,v,1)^\top\) 乘上了一个未知的标量 \(\lambda=Z\):这个"相差一个比例"的等价关系就是齐次坐标,10.2 节会把它做成一个完整的工具;10.3 节把外参 \({}^{c}T_{w}\) 乘进来得到 \(\lambda\tilde{\mathbf u}=K[R\,|\,\mathbf t]\tilde{\mathbf X}\)。注意外参是相机位姿 \({}^{w}T_{c}\) 的逆。

    The right-hand side is linear in \(\mathbf X_c\); the left-hand \(\tilde{\mathbf u}=(u,v,1)^\top\) is multiplied by an unknown scalar \(\lambda=Z\). This "equal up to scale" relation is exactly homogeneous coordinates, which Lesson 10.2 turns into a full tool; Lesson 10.3 multiplies in the extrinsics \({}^{c}T_{w}\) to get \(\lambda\tilde{\mathbf u}=K[R\,|\,\mathbf t]\tilde{\mathbf X}\). Note the extrinsics are the inverse of the camera pose \({}^{w}T_{c}\).

    反投影:像素 → 射线Back-projection: pixel → ray

    求逆只能把 \(\lambda\) 留作自由量:

    Inverting can only leave \(\lambda\) free:

    $$ \mathbf d = K^{-1}\tilde{\mathbf u} = \Big(\tfrac{u-c_x}{f_x},\ \tfrac{v-c_y}{f_y},\ 1\Big)^{\!\top},\qquad \mathbf X_c(Z) = Z\,\mathbf d\ \ (Z>0),\qquad \mathbf X_w = {}^{w}\mathbf t_{c} + Z\;{}^{w}R_{c}\,\mathbf d. $$

    深度 \(Z\) 一旦知道(激光、深度相机、立体视觉、已知尺寸),三维点就确定了。\(\mathbf d\) 是射线方向(未归一化,\(z\) 分量为 1),\({}^{w}\mathbf t_{c}\) 是相机中心,即射线的起点。

    Once the depth \(Z\) is known (laser, depth camera, stereo, known size) the 3D point is fixed. \(\mathbf d\) is the ray direction (unnormalized, with \(z\)-component 1) and \({}^{w}\mathbf t_{c}\) is the camera centre, the ray's origin.

    投影的雅可比及其零空间The projection Jacobian and its null space

    对 \(u=f_xX/Z+c_x\)、\(v=f_yY/Z+c_y\) 求偏导(3.3 节):

    Differentiate \(u=f_xX/Z+c_x\) and \(v=f_yY/Z+c_y\) (Lesson 3.3):

    $$ J=\frac{\partial(u,v)}{\partial(X,Y,Z)}=\frac1Z\begin{bmatrix}f_x&0&-f_x\tfrac{X}{Z}\\[2pt]0&f_y&-f_y\tfrac{Y}{Z}\end{bmatrix},\qquad J\begin{bmatrix}X\\Y\\Z\end{bmatrix}=\frac1Z\begin{bmatrix}f_xX-f_xX\\ f_yY-f_yY\end{bmatrix}=\mathbf 0. $$

    \(J\) 的秩是 2,零空间(1.6 节)由射线方向 \((X,Y,Z)\) 张成。更一般地,投影只依赖于 \(X/Z\) 与 \(Y/Z\),两者在 \(\mathbf X\to s\mathbf X\) 下不变。这也解释了尺度歧义:单目相机观测到的一切都只能确定到整体缩放(本课程之后的单目 SLAM 与运动恢复结构都要面对这一点)。

    \(J\) has rank 2 and its null space (Lesson 1.6) is spanned by the ray direction \((X,Y,Z)\). More generally projection depends only on \(X/Z\) and \(Y/Z\), which are invariant under \(\mathbf X\to s\mathbf X\). That also explains the scale ambiguity: everything a single camera observes is determined only up to a global scale (monocular SLAM and structure from motion, later, must face this).

    已知尺寸 ⇒ 深度,及其误差Known size ⇒ depth, and its error

    若一个垂直于光轴的物体真实长度为 \(S\),像长 \(s\) 像素,则 \(s=f_xS/Z\),即

    If an object perpendicular to the optical axis has true length \(S\) and image length \(s\) pixels, then \(s=f_xS/Z\), i.e.

    $$ Z=\frac{f_x\,S}{s},\qquad \delta Z \approx \Big|\frac{\partial Z}{\partial s}\Big|\,\delta s = \frac{Z^2}{f_x S}\,\delta s,\qquad \frac{\delta Z}{Z}=\frac{\delta s}{s}. $$

    深度误差随距离的平方增长(这与 4.5 节的误差传播同出一辙)。例如 \(S=0.16\) m、\(f_x=600\) px、\(Z=3\) m:\(s=32\) px,像长误差 0.5 px 就带来 \(3^2\cdot0.5/(600\cdot0.16)\approx 4.7\) cm 的深度误差。

    The depth error grows with the square of the distance (the same error propagation as Lesson 4.5). For example with \(S=0.16\) m, \(f_x=600\) px, \(Z=3\) m: \(s=32\) px, and a 0.5 px error in the measured length gives a depth error of \(3^2\cdot0.5/(600\cdot0.16)\approx 4.7\) cm.

    6机器人中的它:由已知尺寸估计距离In robotics: estimating distance from a known size

    机器人常常贴一个尺寸已知的方形标记(AprilTag、ArUco),用它既能认出"这是哪个物体",又能直接估计距离。下面的实验是这个思路的蒙特卡洛版:对 0.5 到 10 m 之间等间隔的 250 个距离,用 \(\tilde s = fS/Z + \) 噪声 测得像长,再用 \(\hat Z = fS/\tilde s\) 估计距离。测量噪声取 \(\sigma_s = \sqrt2\,\sigma\)(一条边的长度由两个角点各带噪声 \(\sigma\) 的位置之差得到)。绿色带是线性化预测的 \(\pm1\sigma\) 范围 \(Z^2\sigma_s/(fS)\):近处几乎看不出误差,远处散点张成喇叭口。

    这个模型是简化的:真实的标记检测器用角点的亚像素位置,并用四个角点通过 PnP(11.4 节)求完整的 6 自由度位姿,不要求标记正对相机;但误差随 \(Z^2\) 增长、与 \(fS\) 成反比的规律是一样的。所以要想看得远,办法只有三条:标记做大、焦距拉长(视场收窄)、噪声压低。

    Robots often put a square marker of known size (AprilTag, ArUco) on things: it identifies "which object this is" and directly gives a distance estimate. The experiment below is a Monte Carlo version of that idea: for 250 evenly spaced distances from 0.5 to 10 m, measure the image length as \(\tilde s = fS/Z + \) noise and estimate the distance as \(\hat Z = fS/\tilde s\). The measurement noise is \(\sigma_s = \sqrt2\,\sigma\) (an edge length is the difference of two corner positions, each with noise \(\sigma\)). The green band is the linearized \(\pm1\sigma\) prediction \(Z^2\sigma_s/(fS)\): negligible error nearby, a trumpet of scatter far away.

    The model is simplified: real marker detectors use sub-pixel corner positions and recover the full 6-DoF pose from the four corners by PnP (Lesson 11.4), without requiring the tag to face the camera; but the law is the same: error grows like \(Z^2\) and is inversely proportional to \(fS\). So to see farther there are only three levers: a bigger tag, a longer focal length (narrower view), or lower noise.

    FIG 6由已知尺寸估计距离:误差随 Z² 增长Distance from a known size: the error grows like Z²
    横轴是真实距离 \(Z\),纵轴是估计 \(\hat Z\);琥珀点是 250 次测量,灰色对角线是理想值,绿色带是 \(\pm1\sigma\)(纵轴截断在 12 m)。"重新采样"换一批噪声。读数中的 \(Z_{5\%}\) 是 \(1\sigma\) 相对误差不超过 5% 的最远距离。 The horizontal axis is the true distance \(Z\) and the vertical axis the estimate \(\hat Z\); amber dots are 250 measurements, the grey diagonal is the ideal, and the green band is \(\pm1\sigma\) (vertical axis cut at 12 m). "Resample" draws fresh noise. \(Z_{5\%}\) in the readout is the farthest distance at which the \(1\sigma\) relative error is at most 5%.
    • 选择参数让 \(Z_{5\%}\) 超过 12 m。你调了哪个旋钮?每个旋钮在真实系统里的代价是什么(视场、成本、体积)?Choose parameters so that \(Z_{5\%}\) exceeds 12 m. Which knob did you turn, and what does each cost in a real system (field of view, price, size)?
    真实系统里In real systems

    选镜头:视场角与分辨率是一对矛盾,\(f_x\) 固定时 FOV 越宽,每个像素覆盖的角度越大。机器人上常见的做法是头部/固定相机用中等视场看全局,腕部相机用广角看到手爪周围;ALOHA 一类的双臂遥操作系统在两条手臂的腕部各装一台相机,再加固定视角;UMI 的手持夹爪用带鱼眼镜头的 GoPro。广角镜头会有明显畸变(10.3 节),所以这两类系统都要把畸变建模。工程接口:ROS 的 sensor_msgs/CameraInfo 就是把 \(K\)(内参)、畸变系数 \(D\)、矫正和投影矩阵 \(R, P\) 放在一条消息里;OpenCV 的 projectPoints、undistort 实现本课的映射。已知尺寸标记:AprilTag、ArUco 等基准标记,OpenCV 的 aruco 模块可用。快门:卷帘快门(rolling shutter)逐行曝光,相机或物体快速运动时图像会扭曲;全局快门(global shutter)整幅同时曝光,高速运动、视觉里程计中更受欢迎。事件相机:每个像素异步地只报告亮度变化,延迟低、动态范围大,但仍然遵循同样的针孔几何。深度相机:Intel RealSense、Azure Kinect、ZED 等把"再多一个传感器"集成在机身里,来解决本课的深度丢失,原理是下面几节的立体视觉、结构光或飞行时间。

    Choosing a lens: field of view and resolution trade off; at fixed \(f_x\) a wider FOV means each pixel spans a larger angle. A common pattern is a mid-FOV head or fixed camera for the overview and a wide-angle wrist camera for the area around the gripper; ALOHA-style bimanual teleoperation setups put a camera on each arm's wrist in addition to fixed views, and UMI's handheld gripper uses a GoPro with a fisheye lens. Wide lenses have strong distortion (Lesson 10.3), so both kinds of systems model it. Software interfaces: ROS's sensor_msgs/CameraInfo packs \(K\) (intrinsics), the distortion coefficients \(D\), and the rectification and projection matrices \(R, P\) in one message; OpenCV's projectPoints and undistort implement this lesson's map. Known-size fiducials: AprilTag and ArUco (OpenCV has an aruco module). Shutters: a rolling shutter exposes row by row so fast camera or object motion skews the image; a global shutter exposes the whole frame at once and is preferred for fast motion and visual odometry. Event cameras report only per-pixel brightness changes, asynchronously, with low latency and high dynamic range, but still obey the same pinhole geometry. Depth cameras (Intel RealSense, Azure Kinect, ZED and the like) build "one more sensor" into the body to resolve this lesson's lost depth, using stereo, structured light or time of flight.

    7常见误区Common pitfalls

    误区 1:焦距的单位(毫米还是像素)Pitfall 1: the unit of the focal length (mm or pixels)

    镜头标注的 4 mm 是毫米,而 \(K\) 里的 \(f_x\) 是像素:\(f_x=f_{\text{mm}}/p\)。把 4 代进 \(K\) 会得到一个"视场角 \(2\arctan(320/4)\approx178^\circ\)"的荒谬相机。同一个镜头换成不同分辨率或不同像元的传感器,\(f_x\) 会变,而视场角取决于焦距与传感器物理尺寸之比。图像被降采样或裁剪后,\(f_x, c_x\) 也要按同样的比例变。另外,镜头的焦距 \(F\) 和针孔模型里的 \(f\)(到像平面的距离)只在对焦于无穷远时相同,近距离对焦会"呼吸":\(f\) 略有变化。

    A lens labelled 4 mm is in millimetres, while \(f_x\) in \(K\) is in pixels: \(f_x=f_{\text{mm}}/p\). Plugging 4 into \(K\) gives an absurd camera with a "field of view of \(2\arctan(320/4)\approx178^\circ\)". The same lens on a sensor with a different resolution or pixel pitch gets a different \(f_x\), and the field of view depends on the focal length relative to the physical sensor size. When an image is downsampled or cropped, \(f_x, c_x\) must scale accordingly. Also, a lens's focal length \(F\) equals the pinhole model's \(f\) (distance to the image plane) only when focused at infinity; focusing close "breathes" and changes \(f\) slightly.

    误区 2:以为透视强弱来自镜头Pitfall 2: believing perspective strength comes from the lens

    "广角拍人像鼻子大"不是镜头的错,而是你离得太近。FIG 4 说明了:站在原地换镜头只改变取景范围(等价于裁剪并放大,信息完全相同);只有移动相机才改变主体与背景的相对大小。所以估计"相机的透视"看的是相机中心的位置,而不是 \(f\)。反过来,在固定位置用更长焦距相当于裁剪;这也是为什么同一位置拍的长焦图像在几何上就是广角图像的局部裁剪(除了景深与分辨率)。

    "Wide-angle portraits give you a big nose" is not the lens's fault: you stood too close. FIG 4 shows it: swapping lenses while standing still only changes the framing (equivalent to cropping and magnifying, with the same information); only moving the camera changes the relative size of subject and background. So perspective is determined by the position of the camera centre, not by \(f\). Conversely, a longer focal length at a fixed position amounts to cropping, which is why a tele image is, geometrically, a crop of a wide image taken from the same spot (apart from depth of field and resolution).

    误区 3:搞错 y 轴和图像的上下Pitfall 3: flipping the y axis or the image

    三个"上下"互相打架:世界 \(z\) 向上,相机系 \(y_c\) 向下,像素 \(v\) 向下(原点左上);针孔的真实像还是倒立的。画图时 Canvas 的 \(y\) 向下,数学图向上,很容易再翻一次。本课所有公式用 \(v\) 向下,FIG 1 为了直观用"高度向上",已经在图注里提示过。看到一张图像上下颠倒或左右镜像,第一反应应该是检查约定,而不是怀疑标定。

    Three "ups" fight each other: world \(z\) is up, the camera \(y_c\) is down, pixel \(v\) is down (origin top-left); and the pinhole's physical image is upside down. When plotting, a canvas \(y\) points down while a math plot points up, so it is easy to flip once more. All formulas here use \(v\) down; FIG 1 uses "height up" for intuition, as its caption says. When an image comes out upside down or mirrored, check conventions first, not the calibration.

    误区 4:把像素坐标当作度量,以为能直接得到三维Pitfall 4: treating pixel coordinates as metric, or expecting 3D from one image

    两个像素相距 100 px 对应多少米?取决于深度(\(Z/f_x\) m/px,FIG 3),也取决于物体是否正对相机。不能在单张图像里量长度,除非已知深度、已知尺寸、或者已知物体位于某个已知平面上(10.5 节的单应就是这种情形:平面把"射线上的哪一点"这个歧义消掉了)。深度学习的单目深度估计是用先验"猜"出深度,其尺度也可能是错的。

    How many metres is 100 px? It depends on the depth (\(Z/f_x\) m/px, FIG 3) and on whether the object faces the camera. You cannot measure lengths in a single image unless the depth, the size, or a known plane containing the object is known (Lesson 10.5's homography is that case: the plane resolves "which point on the ray"). Deep monocular depth estimators "guess" depth from priors, and their scale can be wrong too.

    误区 5:相机后面的点也有"合法"的像素Pitfall 5: points behind the camera also get "valid" pixels

    公式 \(u=f_xX/Z+c_x\) 在 \(Z<0\) 时照样给出一个有限的数。点 \((1,0,-2)\) 与点 \((-1,0,2)\) 投影到同一个像素(\(f_x=500\) 时 \(u=c_x-250\)),因为它们在过针孔的同一条直线上(FIG 3 中红色虚线)。所以任何投影代码在除以 \(Z\) 之前必须检查 \(Z>0\)(本课程的 Vision 辅助函数对 \(Z\le0\) 返回 NaN),三角化和光束法平差里也要检查"点在相机前方"(cheirality)。靠近 \(Z=0\) 的点会投影到无穷远,这在绘制长线段时尤其要裁剪(FIG 2 里每条线都先对近平面裁剪)。

    The formula \(u=f_xX/Z+c_x\) happily returns a finite number for \(Z<0\). The points \((1,0,-2)\) and \((-1,0,2)\) land on the same pixel (\(u=c_x-250\) for \(f_x=500\)) because they lie on the same line through the pinhole (the red dashed part in FIG 3). So every projection routine must check \(Z>0\) before dividing (this course's Vision helper returns NaN for \(Z\le0\)), and triangulation and bundle adjustment must check that points lie in front of the camera ("cheirality"). Points near \(Z=0\) project to infinity, so long segments must be clipped (every line in FIG 2 is clipped against the near plane first).

    8小练习Check yourself

    1. 一辆 1.5 m 高的车在 30 m 外,相机 \(f_x=600\) px,车垂直于光轴。车的像高大约是多少?1. A 1.5 m tall car stands 30 m away, perpendicular to the optical axis; the camera has \(f_x=600\) px. About how tall is the car in the image?
    相似三角形:\(s=f_xS/Z=600\times1.5/30=30\) px。车到了 15 m 就是 60 px:像高与距离成反比。Similar triangles: \(s=f_xS/Z=600\times1.5/30=30\) px. At 15 m it would be 60 px: image height is inversely proportional to distance.
    2. 传感器宽 6.4 mm,镜头焦距 4 mm。水平视场角是多少?2. The sensor is 6.4 mm wide and the lens has a 4 mm focal length. What is the horizontal field of view?
    FOV \(=2\arctan\frac{w}{2f}=2\arctan\frac{3.2}{4}=2\times38.66^\circ\approx77.3^\circ\)。半宽对着半角,所以要乘 2;把 \(w/f\) 直接放进反正切(选项 A 和 D)或忘了乘 2(选项 B)都是常见错误。FOV \(=2\arctan\frac{w}{2f}=2\arctan\frac{3.2}{4}=2\times38.66^\circ\approx77.3^\circ\). The half-width subtends the half-angle, hence the factor 2; putting \(w/f\) straight into the arctangent (A and D) or forgetting the factor 2 (B) are the classic mistakes.
    3. 相机从 3 m 退到 9 m 并想让主体在画面里保持同样大,焦距应当怎么改?背景会怎么样?3. The camera backs away from 3 m to 9 m and should keep the subject the same size in the frame. How must the focal length change, and what happens to the background?
    主体像高 \(\propto f/Z\),要不变就必须 \(f\propto Z\),焦距乘 3。背景与主体的大小比是 \(Z/(Z+D)\),\(Z\) 越大越接近 1,背景相对主体变大。这就是滑动变焦的效果。The subject's image height is \(\propto f/Z\), so \(f\propto Z\): triple \(f\). The background/subject size ratio is \(Z/(Z+D)\), which tends to 1 as \(Z\) grows, so the background grows relative to the subject: that is the dolly zoom.
    4. 点 \((0.5,\,0.25,\,2)\)(相机系,单位 m)的像素,也是下列哪个点的像素,且该点在相机前方?4. The point \((0.5,\,0.25,\,2)\) (camera frame, metres) lands on the same pixel as which of these points that lies in front of the camera?
    同一像素 ⇔ \(X/Z\)、\(Y/Z\) 相同 ⇔ 点在过原点的同一条直线上。\((1,0.5,4)=2\times(0.5,0.25,2)\) 满足;\((1,0.5,2)\) 的 \(X/Z\) 加倍了;\((0.5,0.25,4)\) 的 \(X/Z\) 减半了;\((-0.5,-0.25,-2)=-1\times(\cdot)\) 虽然在同一条直线上,却在相机后面(误区 5)。Same pixel ⇔ same \(X/Z\) and \(Y/Z\) ⇔ the points lie on one line through the origin. \((1,0.5,4)=2\times(0.5,0.25,2)\) works; \((1,0.5,2)\) doubles \(X/Z\); \((0.5,0.25,4)\) halves it; \((-0.5,-0.25,-2)=-1\times(\cdot)\) is on the same line but behind the camera (Pitfall 5).
    5. 投影的 \(2\times3\) 雅可比 \(J=\partial(u,v)/\partial(X,Y,Z)\) 的零空间是什么?5. What is the null space of the \(2\times3\) projection Jacobian \(J=\partial(u,v)/\partial(X,Y,Z)\)?
    \(J\) 是 \(2\times3\),秩最多为 2,所以零空间至少一维。直接代入:\(J(X,Y,Z)^\top=\mathbf 0\)。沿视线移动三维点,像素不变。只有当点恰好在光轴上(\(X=Y=0\))时,视线才与光轴 \((0,0,1)\) 重合;一般情况下并不是。\(J\) is \(2\times3\), so its rank is at most 2 and the null space has dimension at least 1. Plug in: \(J(X,Y,Z)^\top=\mathbf 0\). Moving the 3D point along the line of sight leaves the pixel unchanged. The line of sight coincides with the optical axis \((0,0,1)\) only for a point on the axis (\(X=Y=0\)), not in general.

    9延伸阅读Further reading

    • R. Hartley & A. Zisserman, Multiple View Geometry in Computer Vision, 2nd ed., Cambridge University Press, 2004, Ch. 6 — 相机模型:有限相机、投影矩阵 \(P=K[R|t]\)、主点与焦距、弱透视等仿射相机Camera models: finite cameras, the projection matrix \(P=K[R|t]\), principal point and focal length, affine cameras including weak perspective
    • R. Szeliski, Computer Vision: Algorithms and Applications, 2nd ed., Springer, 2022, Ch. 2 — 图像形成:几何基元与变换、三维到二维投影、镜头与光学、传感器Image formation: geometric primitives and transformations, 3D-to-2D projection, lenses and optics, sensors
    • D. Forsyth & J. Ponce, Computer Vision: A Modern Approach, 2nd ed., Pearson, 2011, Ch. 1 — 几何相机模型:针孔相机、透视投影、弱透视与正交投影Geometric camera models: pinhole cameras, perspective projection, weak perspective and orthographic projection
    • Y. Ma, S. Soatto, J. Košecká & S. S. Sastry, An Invitation to 3-D Vision, Springer, 2004, Ch. 3 — 图像形成:针孔模型、内参矩阵、射影坐标,并有大量与运动恢复结构的联系Image formation: the pinhole model, the intrinsic matrix and projective coordinates, with many ties to structure from motion