【机器学习】计算机图形和深度学习模型NeRF详解(1)
本文深入探讨了计算机图形学基础,为掌握NeRF技术铺路。核心要点包括正向成像模型、3D到3D及3D到2D的转换。这些基础概念不仅帮助我们理解数据集,也满足了学习NeRF的前提。接下来,我们将深入NeRF论文《将场景表示为神经辐射场以进行视图合成》的理论,并利用TensorFlow和Python将其付诸实践。我们期待你的参与和实践,一同探索NeRF的奥秘。
1.引言
1.1.1. NeRF研究的背景
人们在拍照的时候,往往会中各个角度进行拍摄,以呈现出物体的全貌和美丽。下图的照片,拍摄的是一架楼梯,但是拍摄的角度完全不同:
我们可以看到这些图片都是楼梯的照片,但拍摄的角度不同。摄影师拍了三张照片,因为他们不确定只用一张照片就能捕捉到这么美丽的场景,担心会错过正确的视角。
于是,人们开始思考,是否存在一种方法,可以让摄影师从拍摄的有限图片中捕获整个3D场景?
通过这样的方法,人们就可以完整地看到摄影师所观察到的场景,而不只是照片所拍摄的视角的照片,可以与摄影师一起欣赏到各种各样的美景。
2020年,Ben Mildenhall、Pratul P. Srinivasan、Matthew Tancik等人撰写,并于2020年发表在ECCV上的《NeRF:以神经辐射场表示场景进行视图合成》一文中,对从图片到3D建模和渲染进行了深入的讨论。
通过论文描述的方法,我们给算法提供从不同角度拍摄的一盘热狗的照片,通过模型建模和计算,可以精确地生成整个3D场景。
神经辐射场(NeRF)将深度学习与计算机图形学结合在一起,为程序员使用2D照片生成3D效果提供巨大的帮助。
1.2.本文的主要内容
计算机图形学确实是现代技术的一大奇迹,它在多个领域中发挥着关键作用,从娱乐到科学研究。渲染逼真的3D场景不仅令人惊叹,而且在功能上也是至关重要的。NeRF,即神经辐射场,是深度学习在计算机图形学中的一个突破性应用,它允许我们以前所未有的方式理解和渲染复杂的3D场景。
本系列博文将深入探讨如何利用TensorFlow和Keras来实现NeRF技术。在这个系列的第一部分,我们将从基础开始,逐步构建对NeRF的理解。
第一部分:基础介绍
- 相机原理:了解相机如何捕捉3D世界中的图像。
- 数据集探索:熟悉我们将使用的特定数据集,这对于训练NeRF模型至关重要。
教程结构
- 世界坐标系:描述如何表示实际的三维物理世界。
- 相机坐标系:定义虚拟的三维相机空间,这是渲染过程中的关键。
- 坐标变换:学习如何将一个坐标系中的点映射到另一个坐标系。
- 投影变换:理解如何在二维平面上,也就是相机传感器上,形成图像。
- 数据集理解:深入了解NeRF数据集,为模型训练做准备。
实际应用场景
想象你带着相机去户外,发现了一朵引人注目的花。你想要捕捉这一刻,这就需要调整相机的角度、设置和参数,以获得最佳的照片。
2.正向成像模型
整个过程,即从3D世界场景到2D图像的转换,可以通过一个数学模型来描述,这个模型被称为正向成像模型。这个模型可以通过图示来更直观地理解,如图3所示。
通过本博文,读者将获得必要的知识和技能,以应用NeRF技术来渲染逼真的3D场景,并理解其背后的数学原理。这不仅有助于你在电影、游戏开发或虚拟现实等领域中应用这些技术,也为读者打开了探索计算机图形学更深层次奥秘的大门。
正向成像模型是一个复杂的数学过程,它描述了如何将3D世界中的点转换成2D图像上的像素。这个过程通常包括以下几个步骤:
-
世界坐标系:首先,我们考虑3D空间中的点P,它位于世界坐标系中。世界坐标系是一个全局参考框架,用于定义场景中所有物体的位置和形状。在这个坐标系中,每个点都有一个唯一的坐标,通常表示为 ( P(x, y, z) )。
-
坐标变换:接下来,我们需要将点P从世界坐标系转换到相机坐标系。这个转换通常涉及平移(移动点的位置)、旋转(改变点的方向)和缩放(改变点的大小)。这些操作可以通过一个变换矩阵来实现,该矩阵将世界坐标系中的点映射到相机坐标系中的相应点。
-
相机坐标系:相机坐标系是相对于相机的局部参考框架。在这个坐标系中,相机的位置通常被设置为原点,而相机的朝向决定了坐标系的方向。在相机坐标系中,点P的新位置可以表示为 ( P’(x’, y’, z’) )。
-
投影变换:一旦点P被转换到相机坐标系,下一步是将其投影到图像平面上。这个投影过程涉及到透视变换,它模拟了相机镜头的视角和焦距。透视变换将3D空间中的点投影到2D图像平面上,生成图像上的像素位置。
-
图像平面:最终,点P在图像平面上的位置决定了它在最终图像中的像素坐标。这个坐标通常表示为 ( (u, v) ),它对应于图像上的一个特定像素点。
通过这个过程,我们能够将3D世界中的点转换为2D图像上的像素,从而创建出逼真的图像。这种转换是计算机图形学中的一个基础概念,对于理解如何渲染3D场景至关重要。在NeRF技术中,这种正向成像模型被用来指导神经网络学习场景的3D结构和外观,从而实现高质量的3D场景渲染。
2.1.世界坐标系
在计算机图形学中,世界坐标系是一个非常重要的概念,因为它为我们提供了一种在三维空间中描述和定位物体的方式。以下是对世界坐标系的详细解释:
-
定义:世界坐标系是一个全局的参考框架,它定义了场景中所有物体的位置和方向。在这个坐标系中,每个点都有一个唯一的位置,通常由三个坐标值 ( x, y, z ) 来表示。
-
用途:世界坐标系允许我们以一种统一的方式描述场景中的物体,无论它们的大小、形状或相对于其他物体的位置如何。这种一致性对于场景的渲染和物体之间的交互至关重要。
-
点P:当我们提到图4中的点P时,我们指的是在3D空间中的一个具体位置。点P在世界坐标系中的位置可以通过三个坐标来精确描述,例如 ( P(x_1, y_1, z_1) )。
-
坐标系的重要性:世界坐标系为我们提供了一个基准,使得我们可以在不同的坐标系之间转换点的位置。例如,当我们需要将点P转换到相机坐标系时,我们首先需要知道它在世界坐标系中的位置。
-
转换到其他坐标系:在渲染过程中,点P可能需要从世界坐标系转换到其他坐标系,如相机坐标系或屏幕坐标系。这些转换涉及到数学上的变换,如旋转、平移和缩放,它们帮助我们模拟相机的视角和镜头特性。
-
场景构建:在构建3D场景时,世界坐标系是构建物体和场景的基础。设计师和开发者使用这个坐标系来放置物体、设置场景布局,并确保所有元素在空间中的正确位置。
-
与现实世界的联系:世界坐标系的概念与我们在现实世界中对空间的理解相呼应。它帮助我们以一种直观和逻辑的方式在计算机中模拟现实世界的三维空间。
通过理解世界坐标系,我们可以更好地掌握计算机图形学中的基本概念,并为进一步学习如相机坐标系、坐标变换和投影变换等高级主题打下坚实的基础。
在这里,
x
^
w
\hat{x}_{w}
x^w、
y
^
w
\hat{y}_{w}
y^w 和
z
^
w
\hat{z}_{w}
z^w 表示世界坐标系中的三个轴。点P的位置通过向量
X
w
X_{w}
Xw来表示。
X
w
=
∣
X
w
Y
w
Z
w
∣
{X}_{w}= \begin{vmatrix} X_w \\ Y_w\\ Z_w\\ \end{vmatrix}
Xw=
XwYwZw
2.2.相机坐标系
与世界坐标系类似,我们还有一个称为相机坐标系的参考框架,如图5所示。
相机坐标系是一个以相机为中心的参考框架,它与世界坐标系相比具有动态特性。这个坐标系的设计是为了模拟相机在空间中的位置和方向,允许我们根据相机的视角来定位和观察场景中的点。
以下是对相机坐标系的改写描述:
-
相机中心:相机坐标系的原点位于相机的中心,这是相机观察场景的起点。
-
动态性:与世界坐标系的静态性不同,相机坐标系是动态的。当相机移动或旋转时,坐标系也随之变化,以反映相机的新位置和方向。
-
点P的定位:在图6中,点P可以在相机坐标系中被重新定位。这意味着,当我们从相机的视角观察时,点P的位置会根据相机的移动而改变。
-
坐标变换:要将点P从世界坐标系转换到相机坐标系,我们需要应用一系列的数学变换,包括平移和旋转。这些变换确保点P在相机坐标系中的位置与其在世界坐标系中的位置相对应。
-
视角模拟:相机坐标系使我们能够模拟相机的视角,包括其视野范围和方向。这对于渲染场景和创建逼真的图像至关重要。
-
与图像平面的联系:在相机坐标系中定位点P之后,下一步是通过投影变换将其投影到图像平面上。这涉及到将3D空间中的点转换为2D图像上的像素。
-
场景渲染:在渲染3D场景时,相机坐标系是连接世界坐标系和最终图像的关键环节。它帮助我们确定哪些物体在相机的视野内,以及它们在图像中的位置。
通过理解相机坐标系的工作原理和它与世界坐标系的关系,我们可以更深入地掌握计算机图形学中的渲染过程,以及如何使用深度学习技术如NeRF来创建逼真的3D场景渲染。
现在,图4中的点P可以用这两个参考框架来定位,如图6所示。
X
c
=
∣
X
c
Y
c
Z
c
∣
{X}_{c}= \begin{vmatrix} X_c \\ Y_c\\ Z_c\\ \end{vmatrix}
Xc=
XcYcZc
2.3.坐标变换
我们已经确定了两个坐标系:世界坐标系和相机坐标系。现在,我们需要定义这两个坐标系之间的转换关系。
以图6中的点P为例,我们的目标是建立世界坐标
x
^
w
\hat{x}_{w}
x^w与相机坐标
x
^
c
\hat{x}_{c}
x^c之间的转换桥梁。
X
c
=
R
×
(
X
w
−
C
w
)
{X}_{c}=R\times(X_w-C_w)
Xc=R×(Xw−Cw)
其中,R 表示相机坐标系相对于世界坐标系的旋转。这个旋转是由一个矩阵表示的。
R
=
∣
r
11
r
12
r
13
r
21
r
22
r
23
r
31
r
32
r
33
∣
R= \begin{vmatrix} r_{11}&r_{12}&r_{13} \\ r_{21}&r_{22}&r_{23} \\ r_{31}&r_{32}&r_{33} \\ \end{vmatrix}
R=
r11r21r31r12r22r32r13r23r33
[
r
11
r
12
r
13
]
→
\begin{bmatrix} r_{11} & r_{12} & r_{13} \end{bmatrix} →
[r11r12r13]→在世界坐标系中,
x
c
{x}_{c}
xc轴的方向。
[ r 21 r 22 r 23 ] → \begin{bmatrix} r_{21} & r_{22} & r_{23} \end{bmatrix} → [r21r22r23]→ 在世界坐标系中, y c y_c yc轴的方向。
[ r 31 r 32 r 33 ] → \begin{bmatrix} r_{31} & r_{32} & r_{33} \end{bmatrix} → [r31r32r33]→在世界坐标系中, z c z_c zc轴的方向。
C w C_w Cw 代表相机坐标系相对于世界坐标系的位置。这个位置是由一个向量表示的。
我们可以将上述方程展开如下:
X
c
=
R
×
(
X
w
−
C
w
)
X_c=R\times(X_w-C_w)
Xc=R×(Xw−Cw)
⟹
X
C
=
R
×
X
w
−
R
×
C
w
\Longrightarrow X_C =R\times X_w-{R\times C_w}
⟹XC=R×Xw−R×Cw
⟹
X
C
=
R
×
X
w
+
t
\Longrightarrow X_C =R\times X_w+t
⟹XC=R×Xw+t
其中 t 表示平移矩阵,它是 -(R × C_w) 的结果。两个坐标系之间的映射已经设计出来了,但还不完整。在上面的方程中,我们有一个矩阵乘法和一个矩阵加法。如果可能的话,我们总是倾向于将它们压缩为单一的矩阵乘法。为此,我们将使用一个称为齐次坐标的概念。
齐次坐标系统允许我们在一个 N+1 维的空间 x = [ x ~ 0 , x ~ 1 , … , x ~ n , w ] x = [\tilde {x}_0, \tilde{x}_1, \dots, \tilde{x}_{n}, w] x=[x~0,x~1,…,x~n,w]中表示一个 N 维的点 x = [ x 0 , x 1 , … , x n ] x = [x_0, x_1, \dots, x_n] x=[x0,x1,…,xn],其中 w 是一个虚构的变量且 w ≠ 0,这样满足以下条件:
x 0 = x ^ 0 w , x ^ 1 w , . . . x ^ n w x_0=\frac{\hat{x}_0}{w},\frac{\hat{x}_1}{w},...\frac{\hat{x}_n}{w} x0=wx^0,wx^1,...wx^n
使用齐次坐标,我们可以将平移和旋转合并到一个单一的仿射变换矩阵中,从而更方便地进行坐标变换。在 3D 图形和计算机视觉中,这通常是通过将 3D 点 [x, y, z] 转换为齐次坐标 [x, y, z, 1],然后应用一个 4x4 的变换矩阵来实现的。
在计算机图形学和几何学中,为了进行投影变换(如透视投影),我们引入了齐次坐标系统。齐次坐标是一个用于描述几何对象在投影空间中的位置的坐标系统。在3D空间中,一个点的坐标表示为(x, y, z),但在齐次坐标系统中,该点被表示为(x, y, z, w),其中w是一个非零的标量。
对于给定的3D点X_w = (x, y, z),其齐次坐标表示\tilde{X}_w通常取为(x, y, z, 1)。这种转换使得我们可以使用4x4的变换矩阵来进行线性变换,这些变换包括旋转、缩放、平移和投影等。
注意:在齐次坐标系统中,所有形如(kx, ky, kz, k)的点(其中k是非零标量)都表示同一个3D点。因此,我们可以说(x, y, z, 1)和(2x, 2y, 2z, 2)在3D空间中表示的是同一个点。在投影到2D平面时,通常会通过除以w(即透视除法)来得到2D坐标。
X
w
=
∣
x
y
z
1
∣
=
∣
W
X
w
W
Y
w
W
Z
w
W
∣
=
∣
x
^
y
^
z
^
W
∣
=
x
^
w
X_w= \begin{vmatrix} x \\ y \\ z \\ 1\\ \end{vmatrix}= \begin{vmatrix} WX_w \\ WY_w\\ WZ_w\\ W\\ \end{vmatrix}=\begin{vmatrix} \hat{x} \\ \hat{y}\\ \hat{z} \\ W\\ \end{vmatrix}=\hat{x}_w
Xw=
xyz1
=
WXwWYwWZwW
=
x^y^z^W
=x^w
有了齐次坐标,我们可以将方程简化为仅进行矩阵乘法。在计算机图形学和其他几何计算中,使用齐次坐标可以大大简化数学运算。特别是在进行投影变换、仿射变换等操作时,使用齐次坐标可以将这些操作表示为矩阵乘法。这是因为,当我们使用齐次坐标时,一个变换(如旋转、缩放、平移等)可以表示为一个4x4的矩阵,而一个点在齐次坐标下的表示则是一个4x1的向量。这样,我们就可以通过矩阵与向量的乘法来得到变换后的点的坐标,从而大大简化了计算过程。
X
w
=
∣
x
y
z
1
∣
=
∣
R
t
0
1
∣
×
x
^
w
=
∣
r
11
r
12
r
13
t
x
r
21
r
22
r
23
t
y
r
31
r
32
r
33
t
z
0
0
0
1
∣
∣
x
^
y
^
z
^
W
∣
X_w= \begin{vmatrix} x \\ y \\ z \\ 1\\ \end{vmatrix}= \begin{vmatrix} R&t \\ 0&1\\ \end{vmatrix} \times\hat{x}_w=\begin{vmatrix} r_{11}&r_{12}&r_{13} &t_x \\ r_{21}&r_{22}&r_{23}&t_y \\ r_{31}&r_{32}&r_{33} &t_z\\ 0&0&0 &1\\ \end{vmatrix} \begin{vmatrix} \hat{x} \\ \hat{y}\\ \hat{z} \\ W\\ \end{vmatrix}
Xw=
xyz1
=
R0t1
×x^w=
r11r21r310r12r22r320r13r23r330txtytz1
x^y^z^W
⟹
X
^
c
=
C
e
x
×
X
^
w
\Longrightarrow \hat{X}_c=C_{ex}\times\hat{X}_w
⟹X^c=Cex×X^w
C
e
x
C_{ex}
Cex是一个矩阵,它保存了相机坐标系的方向和位置。我们可以称这个矩阵为相机外参矩阵(Camera Extrinsic Matrix),因为它表示了旋转和平移这样的值,而这两者都是相机的外部属性。
- 外参矩阵(Extrinsic Matrix):在摄影测量、计算机视觉和机器人学中,外参矩阵通常用于描述一个坐标系(例如相机坐标系)相对于另一个坐标系(例如世界坐标系)的旋转和平移。
- 旋转(Rotation):表示一个坐标系相对于另一个坐标系的旋转方向和角度。
- 平移(Translation):表示一个坐标系原点相对于另一个坐标系原点的位移。
∣ r 11 r 12 r 13 t x r 21 r 22 r 23 t y r 31 r 32 r 33 t z 0 0 0 1 ∣ \begin{vmatrix} r_{11}&r_{12}&r_{13} &t_x \\ r_{21}&r_{22}&r_{23}&t_y \\ r_{31}&r_{32}&r_{33} &t_z\\ 0&0&0 &1\\ \end{vmatrix} r11r21r310r12r22r320r13r23r330txtytz1
2.4 投影变换
我们起始于一个点P及其在(齐次)世界坐标系下的坐标 X ~ w \tilde{X}_w X~w。借助相机外参矩阵 C e x C_{ex} Cex,我们成功地将 X ~ w \tilde{X}_w X~w转换为其在(齐次)相机坐标系下的坐标 X ~ c \tilde{X}_c X~c。
现在,我们进入最终阶段,即将3D相机坐标(\tilde{X}_c)投影为二维图像上的点,如图7所示。
为了深入理解投影变换,关键在于理解相似三角形的概念。首先,我们简要介绍一下相似三角形。
在图8和图9中,我们展示了相似三角形的实例。
A
B
A
′
B
′
=
C
B
C
′
B
′
\frac{AB}{A'B'}=\frac{CB}{C'B'}
A′B′AB=C′B′CB
从相似三角形的性质中,我们可以推导出
x
i
f
=
x
c
z
c
;
y
i
f
=
y
c
z
c
\frac{x_i}{f}=\frac{x_c}{z_c};\frac{y_i}{f}=\frac{y_c}{z_c}
fxi=zcxc;fyi=zcyc
因此
x
i
=
f
×
x
c
z
c
x_i=f\times\frac{x_c}{z_c}
xi=f×zcxc
y
i
=
f
×
y
c
z
c
y_i=f\times\frac{y_c}{z_c}
yi=f×zcyc
现在重要的是要记住,实际的图像平面不是一个虚拟的平面,而是一个图像传感器阵列。3D场景落在这个传感器上,从而形成图像。因此,图像平面上的
x
i
x_i
xi和
y
i
y_i
yi可以用像素值 u,v 来代替。
u
=
f
×
x
c
z
c
u=f\times\frac{x_c}{z_c}
u=f×zcxc
v
=
f
×
y
c
z
c
v=f\times\frac{y_c}{z_c}
v=f×zcyc
图像平面上的一个像素从左上角(0,0)开始,因此也需要相对于图像平面的中心来移动这些像素。
u
=
f
×
x
c
z
c
+
o
x
u=f\times\frac{x_c}{z_c}+o_x
u=f×zcxc+ox
v
=
f
×
y
c
z
c
+
o
y
v=f\times\frac{y_c}{z_c}+o_y
v=f×zcyc+oy
这里,o_x 和 o_y 是图像平面的中心点。
现在我们有一个来自3D相机空间的点,它在图像平面上用u,v来表示。再次为了让矩阵保持一致,我们需要使用齐次坐标来表示像素值。
u,v的齐次坐标表示,其中
u
=
u
~
w
~
u = \frac{\tilde{u}}{\tilde{w}}
u=w~u~和
v
=
v
~
w
~
v = \frac{\tilde{v}}{\tilde{w}}
v=w~v~。
∣
u
v
1
∣
=
∣
u
^
v
^
w
^
∣
=
∣
z
c
u
z
c
v
z
c
∣
\begin{vmatrix} u\\ v \\ 1\\ \end{vmatrix}=\begin{vmatrix} \hat{u}\\ \hat{v}\\ \hat{w}\\ \end{vmatrix}=\begin{vmatrix} {z_cu}\\ {z_cv}\\ {z_c}\\ \end{vmatrix}
uv1
=
u^v^w^
=
zcuzcvzc
等价的表达方式如下
∣
z
c
u
z
c
v
z
c
∣
=
∣
f
0
o
x
0
0
f
o
y
0
0
0
1
0
∣
∣
x
c
y
c
z
c
1
∣
\begin{vmatrix} {z_cu}\\ {z_cv}\\ {z_c}\\ \end{vmatrix}=\begin{vmatrix} f&0&o_x&0\\ 0&f&o_y&0\\ 0&0&1&0\\ \end{vmatrix}\begin{vmatrix} {x_c}\\ {y_c}\\ {z_c}\\ {1}\\ \end{vmatrix}
zcuzcvzc
=
f000f0oxoy1000
xcyczc1
最终,我们可以得出
∣
u
v
1
∣
=
∣
f
0
o
x
0
0
f
o
y
0
0
0
1
0
∣
∣
x
c
y
c
z
c
1
∣
\begin{vmatrix} u\\ v \\ 1\\ \end{vmatrix}=\begin{vmatrix} f&0&o_x&0\\ 0&f&o_y&0\\ 0&0&1&0\\ \end{vmatrix}\begin{vmatrix} {x_c}\\ {y_c}\\ {z_c}\\ {1}\\ \end{vmatrix}
uv1
=
f000f0oxoy1000
xcyczc1
简化的表达如下
u
^
=
C
i
n
×
x
^
c
\hat{u}=C_{in}\times\hat{x}_c
u^=Cin×x^c
其中
x
~
c
\tilde{x}_c
x~c 是一组向量,包含点在相机坐标系中的位置,而
u
^
\hat{u}
u^ 是一组值,包含点在图像平面上的位置。相应地,
C
i
n
C_{in}
Cin 代表一组值,用于将点从3D相机空间映射到2D空间。
C
i
n
=
∣
f
0
o
x
0
0
f
o
y
0
0
0
1
0
∣
C_{in}=\begin{vmatrix} f&0&o_x&0\\ 0&f&o_y&0\\ 0&0&1&0\\ \end{vmatrix}
Cin=
f000f0oxoy1000
我们可以称
C
i
n
C_{in}
Cin 为相机内参,因为它代表了诸如焦距和图像平面沿x和y轴的中心等值,这些都是相机的内部属性。
3.数据集
好了,既然你想看到代码和数据集处理的初步步骤,我们可以开始编写一个简单的代码示例来加载和预处理数据集。但请注意,由于完整的NeRF实现会非常复杂,这里我们只展示如何开始处理数据集的初步步骤。
首先,你需要从NeRF的官方仓库或提供的链接中下载数据集。数据集通常包含多个文件夹,每个文件夹代表一个场景,而每个场景又包含多个从不同视角拍摄的图片以及相关的相机参数。
我们将关注nerf_synthetic文件夹,因为我们将使用其中的合成数据集进行后续操作。为了理解数据集的结构,我们可以查看图12,它给出了nerf_synthetic文件夹中数据的布局示例。通常,这样的合成数据集会包含多个场景,每个场景都有自己的文件夹,里面存储了从多个不同视角捕获的图像以及相关的相机参数。这些数据是训练和评估NeRF(神经辐射场)模型所必需的。在后续步骤中,我们将编写代码来加载和预处理这些数据,以便能够将其输入到NeRF模型中。
这里有很多合成对象。让我们下载其中一个看看里面是什么。我们选择了“船”数据集,但你可以随意下载任何一个。
解压数据集后,你会发现有三个文件夹包含图像:
- train(训练集)
- val(验证集)
- test(测试集)
以及三个包含相机方向和位置的文件:
- transforms_train.json
- transforms_val.json
- transforms_test.json
为了更好地理解这些json文件,我们可以打开一个新的Colab笔记本并上传transforms_train.json。现在我们可以对它进行探索性数据分析。
# 导入必要的包
import json
import numpy as np
# 定义json训练文件
jsonTrainFile = "transforms_train.json"
# 打开文件并读取文件内容
with open(jsonTrainFile, "r") as fp:
jsonTrainData = json.load(fp)
# 打印json文件的内容
print(f"[INFO] 训练集的焦距:{jsonTrainData['camera_angle_x']}")
print(f"[INFO] 训练集的帧数:{len(jsonTrainData['frames'])}")
# 输出
# [INFO] 训练集的焦距:0.6911112070083618
# [INFO] 训练集的帧数:100
我们从第2行和第3行开始导入必要的包json和numpy。
然后在第6-10行加载json并读取其值。
json文件有两个父键称为camera_angle_x和frames。我们看到camera_angle_x对应于相机的视野,而frames是每个图像(帧)的元数据集合。
在第13行和第14行,我们打印json键的值。第17行和第18行显示输出。
让我们进一步调查frames。
# 获取第一帧
firstFrame = jsonTrainData["frames"][0]
# 获取变换矩阵和文件名
tMat = np.array(firstFrame["transform_matrix"])
fName = firstFrame["file_path"]
# 打印数据
print(tMat)
print(fName)
# 输出
# array([[-0.92501402, 0.27488998, -0.26226836, -1.05723763],
# [-0.37993318, -0.66926789, 0.63853836, 2.5740304 ],
# [ 0. , 0.6903013 , 0.72352195, 2.91661024],
# [ 0. , 0. , 0. , 1. ]])
# ./train/r_0
我们在第20行获取第一帧。每一帧是一个字典,包含两个键,transform_matrix和file_path,如第23行和第24行所示。file_path是正在考虑的图像(帧)的路径,而transform_matrix是该图像的相机到世界矩阵。
在第27行和第28行,我们打印了变换矩阵(transform_matrix)和文件路径(file_path)。第31行到第35行显示了输出结果。
4.总结
在本文中,我们深入了解了计算机图形学的基本概念,这是掌握NeRF技术的基础。虽然我们讨论的内容属于基础知识,但它对于我们进一步的学习至关重要。
我们可以将所学内容简化为三个核心要点:
- 正向成像模型:理解如何捕捉图像的过程。
- 3D到3D的转换:学习如何将世界坐标系中的点转换到相机坐标系。
- 3D到2D的转换:掌握如何将相机坐标系中的点投影到二维图像平面。
通过这些步骤,我们不仅理解了数据集的使用,也满足了学习NeRF所需的所有前提条件。
在接下来的课程中,我们将探讨NeRF论文《将场景表示为神经辐射场以进行视图合成》的深层概念。同时,我们将学习如何利用TensorFlow和Python将这些理论概念转化为实践应用。
我们期待你在本教程中有所收获,并鼓励你下载相应的数据集进行实践操作。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)