QiuQiu

Robotics - Seneing - Coordinates

Pc​=(X,Y,Z) 中的下标 cc 表示 camera。相机坐标系不是相机里画着的三根轴,而是人为固定在相机上的一个三维参考系。

通常这样建立:

  1. 原点 OcO_c:设在相机的等效光心(投影中心)。
  2. ZcZ_c 轴:沿相机光轴,指向相机前方。
  3. XcX_c 轴:与图像水平方向平行,指向图像右侧。
  4. YcY_c 轴:与图像垂直方向平行,指向图像下方。

对于 RealSense/OpenCV 常用的光学坐标约定:

Xc:右,Yc:下,Zc:前\boxed{ X_c:\text{右},\qquad Y_c:\text{下},\qquad Z_c:\text{前} }

因此,一个点:

Pc=(X,Y,Z)P_c=(X,Y,Z)

表示的是:

从相机光心出发,这个点向右 XX、向下 YY、向前 ZZ。

例如:

Pc=(0.1,0.05,1.0) mP_c=(0.1,0.05,1.0)\ \text{m}

表示这个点位于相机:

它与图像坐标的关系

因为 XcX_c 向右、YcY_c 向下,所以:

X>0⇒u>cxX>0 \Rightarrow u>c_x

点会出现在主点右边。

Y>0⇒v>cyY>0 \Rightarrow v>c_y

点会出现在主点下边。

Z>0Z>0

表示点位于相机前方,可以被相机看到。

因此投影公式可以直接写成:

u=fxXZ+cxu=f_x\frac{X}{Z}+c_x v=fyYZ+cyv=f_y\frac{Y}{Z}+c_y

相机坐标不是机身外壳坐标

这里的原点不是:

而是该成像模型的等效光心

对于 D435,还必须说明是哪个相机坐标系,因为它内部有多个相机:

它们的原点位置并不完全相同,相互之间通过外参转换。例如,一个点已经在深度相机坐标系中表示为 PdP_d,要转到 RGB 相机坐标系:

Prgb=Rrgb←dPd+trgb←dP_{\text{rgb}} = R_{\text{rgb}\leftarrow d}P_d + t_{\text{rgb}\leftarrow d}

相机是怎么知道 X,Y,ZX,Y,Z 的?

普通 RGB 相机从一个像素 (u,v)(u,v) 只能得到观察方向:

XZ=u−cxfx,YZ=v−cyfy\frac{X}{Z}=\frac{u-c_x}{f_x}, \qquad \frac{Y}{Z}=\frac{v-c_y}{f_y}

不知道具体距离 ZZ,所以无法单独确定 X,Y,ZX,Y,Z。

D435 通过双目计算出深度 ZZ 后,就可以反投影:

X=u−cxfxZ\boxed{ X=\frac{u-c_x}{f_x}Z } Y=v−cyfyZ\boxed{ Y=\frac{v-c_y}{f_y}Z } Z=Z\boxed{ Z=Z }

也就是说:

像素位置 (u,v)+深度 Z⟶相机坐标 (X,Y,Z)\text{像素位置 }(u,v)+\text{深度 }Z \longrightarrow \text{相机坐标 }(X,Y,Z)

最直观的理解是:

把相机光心当作你的一只眼睛:正前方是 ZZ,画面右边是 XX,画面下边是 YY。Pc=(X,Y,Z)P_c=(X,Y,Z) 就是在描述一个点相对于这只“眼睛”的位置。

这个跟2d lines不是一回事, 虽然都是3个数