文章目录
- 相机坐标系、世界坐标系与光轴:单双目的本质区别到底在哪
- 一、先厘清坐标系之间的关系
- 二、双目 vs 单目:坐标系上的差异
- 双目:天然知道两相机的相对位置
- 单目:只有一个相机坐标系
- 三、为什么双目能恢复真实尺度,单目不能?
- 双目:有基线,就有几何约束
- 单目:一个像素对应一整条射线
- 双目:视差给出唯一解
- 小结对比
- 四、光轴(Optical Axis)到底在哪?
- 如何确定自己的光轴?三种方法
- 五、辨析:“图片中心是光轴”和“中心点高度不等于相机高度”矛盾吗?
- 情况一:真正水平安装 → 高度不变
- 情况二:有俯角(最常见)→ 越远越低
- 另一个更隐蔽的坑:不要混淆两个 Y
- 六、总结与下一步
相机坐标系、世界坐标系与光轴:单双目的本质区别到底在哪
学双目深度估计的人,几乎都会在“坐标系”这一关卡住:单目和双目的世界坐标有什么区别?为什么双目能测真实距离而单目不能?相机的光轴到底在哪、图片中心是不是光轴?这篇文章把这些串成一条线。
先纠正一个最常见的误解:
双目没有自己的“世界坐标”,单目也没有。世界坐标系与单/双目没有直接关系,它是由标定(外参)人为定义的。单双目真正的区别,在于能否恢复具有真实尺度的三维点。
一、先厘清坐标系之间的关系
工程里最常用的思维方式是把坐标分成四层,从三维世界一路投影到像素:
而世界坐标与左右相机的关系是:
世界坐标只有一个,左右相机各有自己的相机坐标系。世界坐标点P w P_wPw与相机坐标点P c P_cPc通过外参相互变换:
P w = R P c + t P_w = R\,P_c + tPw=RPc+t
二、双目 vs 单目:坐标系上的差异
双目:天然知道两相机的相对位置
俯视图 左相机 右相机 ●----------------------● Baseline = B约定左相机坐标系为参考。这里采用 OpenCV/针孔相机成像模型的惯例:X 向右、Y 向下(与图像行坐标v vv同向)、Z 向前(朝向场景)——正是这个约定,让后文的反投影公式Y = ( v − c y ) Z / f y Y=(v-c_y)Z/f_yY=(v−cy)Z/fy直接成立。
Camera ●────────→ X(向右) │ \ │ \ ↓ ↘ Z(向前,朝向场景) Y(向下)右相机坐标系只是相对左相机平移了一个基线B BB,即X 右 = X 左 − B X_{右} = X_{左} - BX右=X左−B(符号取决于基线方向约定,此处右相机相对左相机沿 +X 平移B BB),其余轴相同。所以双目天然知道两个相机之间的位置关系——这正是它能三角测量的前提。
单目:只有一个相机坐标系
单目只有一个 Camera 坐标系,没有第二个相机作参照,因此不知道真实尺度(scale)。
三、为什么双目能恢复真实尺度,单目不能?
双目:有基线,就有几何约束
因为知道 Baseline(比如 60 mm),利用Z = f B d Z = \dfrac{fB}{d}Z=dfB就能直接算出真实长度的Z ZZ(比如 2.35 m),而不是一个比例。
单目:一个像素对应一整条射线
单目从像素( u , v ) (u,v)(u,v)无法唯一恢复( X , Y , Z ) (X,Y,Z)(X,Y,Z)。一个像素( 500 , 300 ) (500,300)(500,300)对应的其实是从光心出发的一条射线,目标可能在 1 m、2 m、5 m、20 m……都说得通:
Camera / / / Pixel → 一条射线,无唯一解所以单目存在尺度歧义(scale ambiguity),只能靠学习或额外信息去“猜”深度。
双目:视差给出唯一解
左图( u L , v ) (u_L, v)(uL,v)、右图( u R , v ) (u_R, v)(uR,v)得到视差d = u L − u R d = u_L - u_Rd=uL−uR,于是能唯一恢复( X , Y , Z ) (X,Y,Z)(X,Y,Z):
一个最形象的类比:单目像闭上一只眼,你知道前面有个箱子,但猜不准 2 m 还是 5 m;双目像睁着两只眼,大脑自动三角测量,恢复真实距离。
小结对比
| 世界坐标系 | 相机坐标系 | 恢复三维能力 | |
|---|---|---|---|
| 单目 | 由外参定义,可任选原点 | 只有一个 | 有尺度歧义,只能估计 |
| 双目 | 同左(无本质区别) | 左、右两个,通常以左为参考 | 靠基线+视差恢复真实尺度 |
四、光轴(Optical Axis)到底在哪?
理解了坐标系,再看光轴就简单了。对针孔相机:
图像 +-------------------+ | | | ● cx,cy | ← 主点(Principal Point) | | +-------------------+ │ │ 光轴 ▼ 相机前方光轴 = 从相机光心(Optical Center)穿过图像主点( c x , c y ) (c_x, c_y)(cx,cy)向前延伸的直线。
严格来说,是主点( c x , c y ) (c_x, c_y)(cx,cy)对应的射线,而不是几何中心( W / 2 , H / 2 ) (W/2, H/2)(W/2,H/2)——很多相机c x ≈ W / 2 c_x ≈ W/2cx≈W/2、c y ≈ H / 2 c_y ≈ H/2cy≈H/2,但标定后往往有几像素偏差(例如理论中心 320,240,实际标定c x = 317.8 c_x=317.8cx=317.8、c y = 236.5 c_y=236.5cy=236.5)。近距离影响很小,但反投影到几十米时误差会被放大。
如何确定自己的光轴?三种方法
理论方法(推荐):根据标定得到的相机内参( f x , f y , c x , c y ) (f_x,f_y,c_x,c_y)(fx,fy,cx,cy),将主点( c x , c y ) (c_x,c_y)(cx,cy))反投影到三维,得到方向( 0 , 0 , 1 ) (0,0,1)(0,0,1)。这条经过相机光心的射线就是光轴。
工程验证方法:让一张平整的 A4 纸逐渐调整姿态,直到其充满画面且左右边缘宽度一致,此时纸面基本垂直于光轴,可用于验证光轴方向。
PnP 方法:使用棋盘格或 ChArUco 标定板,通过 PnP 求解相机位姿,从而获得光轴在世界坐标系中的方向。这适合需要把光轴表示到世界坐标系中的场景。
可以用反投影公式验证:
X = ( u − c x ) Z f x , Y = ( v − c y ) Z f y X = \frac{(u - c_x)Z}{f_x}, \qquad Y = \frac{(v - c_y)Z}{f_y}X=fx(u−cx)Z,Y=fy(v−cy)Z
当u = c x , v = c y u = c_x, v = c_yu=cx,v=cy时,必然X = 0 , Y = 0 X = 0, Y = 0X=0,Y=0——说明这条射线就是光轴。
五、辨析:“图片中心是光轴”和“中心点高度不等于相机高度”矛盾吗?
很多人做实验会发现一个“怪现象”:明明图片中心是光轴,为什么反投影出来的中心点,其世界坐标高度和相机的世界坐标高度对不上?
两句话并不矛盾:
- 图片中心(主点)对应的射线,确实是光轴;
- 但光轴上各点的世界坐标高度,只有在相机真正水平安装时才都相等。
情况一:真正水平安装 → 高度不变
侧视图 光轴 Camera ●──────────────► ------------------------- 地面相机高 1.0 m,则光轴上 1 m 前、2 m 前、5 m 前的点高度都是 1.0 m,世界高度不变。
情况二:有俯角(最常见)→ 越远越低
哪怕只有 Pitch = −5°:
侧视图 Camera \ \ \ ► 光轴 ---------------- 地面相机高 1.0 m,则前方 1 m 处约 0.91 m、2 m 处约 0.83 m、3 m 处约 0.74 m——图片中心对应点的世界高度当然越来越低。扫地机器人常有 20°~45° 俯角,汽车约 3°,无人机约 15°,所以世界高度必然变化。这不是 bug。
另一个更隐蔽的坑:不要混淆两个 Y
相机坐标系的 Y(OpenCV 里向下)和世界坐标系的“高度”通常不是同一个轴:
- ROS:Z 是高度;
- 很多机器人:Y 是高度;
- OpenCV 相机系:Y 向下。
所以千万不要直接拿“相机坐标 Y”去比较“世界坐标高度”,它们往往不是一个轴。要比较,必须先经外参P w = R P c + t P_w = R P_c + tPw=RPc+t变换到同一坐标系。
六、总结与下一步
- 世界坐标不是双目/单目自带的,而是由外参人为定义;单双目在世界坐标系上没有本质区别。
- 单双目真正的区别是恢复三维的能力:双目靠基线+视差恢复真实尺度,单目有尺度歧义。
- 光轴 = 光心穿过主点( c x , c y ) (c_x,c_y)(cx,cy)的射线;用主点而非几何中心,可用反投影验证。
- 光轴水平 ⇒ 高度不变只在相机真正水平时成立;有俯角时中心点世界高度随距离变化,属正常现象。
- 注意区分相机坐标 Y 与世界坐标高度,二者常不是一个轴。
真正打通任督二脉的一步,是完整走一遍像素坐标 → 相机坐标 → 世界坐标的链路(内参、外参、深度反投影、坐标变换)。走通之后,下一篇《Depth ≠ Distance:如何正确评估双目深度算法》里关于 Depth、Distance、Point Cloud、Ground Truth 的所有疑惑,都会自然串起来。