渲染的一般步骤
- 创建场景(Scene):为3D对象、光源、材质等元素提供容器。
- 创建几何体(TriangleMeshModel):创建场景中的3D对象,并组织其顶点、面、纹理坐标等信息。
- 创建材质(MaterialRecord):定义几何体的表面属性。
- 向场景添加几何体:将创建的几何体和材质添加到场景中。
- 设置相机参数:确定场景中的视点位置、方向、观察范围等。
- 设置渲染器(Renderer)以及视图(View)属性:配置渲染设置,例如分辨率、视角等。
open3d坐标系

- 红色轴为x
- 绿色轴为y
- 蓝色轴为z
其实很好记,就是RGB,分别对应xyz轴。
open3d的三维坐标系为右手系
右手大拇指指向x,食指指向y,若中指指向z则为右手系,否则为左手系。注意,本文的讨论包括理论计算都默认在右手系下
Camera
相机的定义方式有两种,可以给相机的位置和姿态或者给相机的内外参矩阵。
- FOV
- 相机位置
- 相机看向的位置 eye (相机坐标系的z轴)
- 相机朝上的方位 up (相机坐标系的y轴)
相机的成像范围如图所示,在一定FOV(由焦距和传感器尺寸决定)下,对一定深度范围(Near-Far)中的场景进行成像。假如相机的内参矩阵为:
\[ K = \left[ \begin{matrix} f_x & 0 & u_x \\ 0 & f_y & u_y \\ 0 & 0 & 1 \end{matrix} \right] \] 传感器的长和宽分别为h, w,则有 \[ h/2 = tan(FOV_y/2) f_y \\ w/2 = tan(FOV_w/2) f_x \]
如何确定相机的内参
确定相机参数需要知道相机的焦距(f_x, f_y)和画幅大小(H, W),一般可以将做目标图像的尺寸作为画幅大小 \[ K = \left[ \begin{matrix} f_x & 0 & W/2 \\ 0 & f_y & H/2 \\ 0 & 0 & 1 \end{matrix} \right] \]
如何确定相机的外参
相机外参描述的是一系列的旋转、平移操作,包含一个旋转矩阵R和一个平移向量t=-RC,其中:3*3的旋转矩阵R的行描述的是相机坐标系在世界坐标系中的表示,向量C是世界坐标系表示的相机中心。其表示的物理含义是,先将世界坐标系原点移动到相机坐标系原点,然后再旋转到相机坐标系:\(X_{cam}=R(X_{world}-C)\)
注意:该矩阵描述如何将世界坐标系中的点转换到相机坐标系下,其中向量
t描述的是世界坐标系原点在相机坐标系中的位置。

求解方法1:求出在世界坐标系下的相机坐标的位置和相机坐标系三个轴的方向向量
按照以上定义,假如知道了世界坐标系下相机的位置\(C\),以及相机坐标系的x轴,y轴,z轴的方向向量\([r_1, r_2, r_3]、[r_4, r_5, r_6]、[r_7, r_8, r_9]\)(均为单位向量),则世界坐标系到相机坐标系的旋转矩阵为 \[ R = \left[ \begin{matrix} r_1 & r_2 & r_3\\ r_4 & r_5 & r_6 \\ r_7 & r_8 & r_9 \end{matrix} \right] \] 对应的\(t\)为 \[ t = -RC \] 即可求出外参矩阵\([R|-RC]\)。
证明
假设\(\mathbf{w1}=[1, 0, 0]^T, \mathbf{w2}=[0, 1, 0]^T, \mathbf{w3}=[0, 0, 1]^T\)分别为世界坐标系x轴、y轴、z轴方向的基向量,而相机的x轴、y轴、z轴方向的基向量分别为\(\mathbf{c1}、\mathbf{c2}、\mathbf{c3}\),则相机坐标系的基向量可以由世界坐标系的基向量通过线性组合表示,且线性组合系数即为坐标值,即 \[ \begin{aligned} \mathbf{c1}=r_1\mathbf{w1}+r_2\mathbf{w2}+r_3\mathbf{w3} \\ \mathbf{c2}=r_4\mathbf{w1}+r_5\mathbf{w2}+r_6\mathbf{w3} \\ \mathbf{c3}=r_7\mathbf{w1}+r_8\mathbf{w2}+r_9\mathbf{w3} \\ \end{aligned} \] 写成矩阵乘法即为 \[ C=W R \\ \] 其中 \(R = \left[ \begin{matrix} r_1 & r_2 & r_3\\ r_4 & r_5 & r_6 \\ r_7 & r_8 & r_9 \end{matrix} \right]\),为世界坐标系基向量到相机坐标系基向量的变换矩阵,即旋转矩阵,而\([r_1, r_2, r_3]、[r_4, r_5, r_6]、[r_7, r_8, r_9]\)恰好分别为世界坐标系下相机坐标系的x轴、y轴、z轴方向向量的坐标表示。
求解方法2:求出世界坐标系到相机坐标系的欧拉角
根据相机外参的定义\([R, t]=[R, -RC]\),\(C\)是相机坐标系原点在世界坐标系下的位置,可以将世界坐标系原点挪到C处,然后旋转世界坐标系的y轴、x轴、z轴,直到世界坐标系的xyz轴与相机坐标系的xyz轴重合,此刻得到的旋转角\(\alpha\)、\(\beta\)、\(\gamma\)为欧拉角,旋转矩阵可由欧拉角计算得到: \[ R(\alpha, \beta, \gamma)= R_y(\alpha)R_x(\beta)R_z(\gamma)\\ = \left[ \begin{matrix} c_1c_3+s_1s_2s_3 & c_3s_1s_2-c_1s_3 & c_2s_1 \\ c_2 s_3 & c_2c_3 & -s_2 \\ c_1 s_2 s_3 - s_1 c_3 & s_1 s_3 + c_1 c_3 s_2 & c_1 c_2 \end{matrix} \right] \\ \] 其中: \[ \begin{aligned} c_1=cos(\alpha), s_1=sin(\alpha) \\ c_2=cos(\beta), s_2=sin(\beta) \\ c_3=cos(\gamma), s_3=sin(\gamma) \end{aligned} \]
⚠️左手系下改公式需要做相应的调整
之后可以得到外参矩阵的\(t\) \[ t=-RC \]
待续...
外部参数Rt的物理含义
当Rt是在右手坐标系中定义时
- R的第i行表示的是相机坐标系中第i个坐标轴方向的单位向量在世界坐标系中的位置
- R的第i列表示的是世界坐标系中第i个坐标轴方向的单位向量在相机坐标系中的位置
- t表示的是世界坐标系的原点在相机坐标系中的坐标
- \(-R^Tt\)表示的是相机坐标系的原点在世界坐标系的位置
- \(P_c=RP_w+t\),\(Rt\)可以将世界坐标系中的坐标变换到相机坐标系中的坐标
常见坐标系手性
- Blender:右手坐标系,z轴朝上
- UE4:左手坐标系,z轴朝上
- OpenGL:右手坐标系,z轴朝前
- colmap坐标系:右手坐标系,z轴朝后,x轴朝右
参考:
https://zhuanlan.zhihu.com/p/405306563
https://zhuanlan.zhihu.com/p/45404840