NeRF 구현을 위해 ray casting을 공부한 내용을 이곳에 기록한다.
NeRF 구현을 위해 dataset을 다운 받으면 다음과 같이 나와있다.
{
"camera_angle_x": 0.6911112070083618,
"frames": [
{
"file_path": "./train/r_0",
"rotation": 0.012566370614359171,
"transform_matrix": [
[
-0.9999021887779236,
0.004192245192825794,
-0.013345719315111637,
-0.05379832163453102
],
[
-0.013988681137561798,
-0.2996590733528137,
0.95394366979599,
3.845470428466797
],
[
-4.656612873077393e-10,
0.9540371894836426,
0.29968830943107605,
1.2080823183059692
],
[
0.0,
0.0,
0.0,
1.0
]
]
},
{
"file_path": "./train/r_1",
"rotation": 0.012566370614359171,
"transform_matrix": [
[
-0.9305422306060791,
0.11707554012537003,
-0.34696459770202637,
-1.398659110069275
],
[
-0.3661845624446869,
-0.29751041531562805,
0.8817007541656494,
3.5542497634887695
],
[
7.450580596923828e-09,
0.9475130438804626,
0.3197172284126282,
1.2888214588165283
],
[
0.0,
0.0,
0.0,
1.0
]
]
},
이게 뭘까
일단 자료를 조금 찾아보다 보면 결국 이런 형식으로 나옴을 알 수 있다.
{
"camera_angle_x": 0.6911112070083618,
"frames": [
{
"file_path": "./train/r_0",
"rotation": 0.012566370614359171,
"transform_matrix": [
[
//r11,
//r12,
//r13,
//tx
],
[
//r21,
//r22,
//r23,
//ty
],
[
//r31,
//r32,
//r33,
//tz
],
[
0.0,
0.0,
0.0,
1.0
]
]
},
즉, $\begin{bmatrix} 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{bmatrix}$를 의미한다. 위에 태그에서 볼 수 있듯이, 이는 transfom의 기능을 해주는데, 정확히 무엇을 무엇으로 transform하는 것인지 확인해보자.
우선 좌표계를 헷갈리면 안 된다.

위와 같이, 바라보는 시점을 기준으로 x-y를 나누며, 사실 생각해보면 당연하다. 결국엔 2D로 변환할 건데 x-y 평면이 내가 바라보는 시점과 수직해야할테니까.
그래서 뒤쪽에 Z의 값에 -1을 곱하라는 의미도 이런 의미에서 비롯된다. 우리는 앞을 보고 있는데 Z축의 양의 방향은 우리를 향해 있으니.
카네기 멜론의 slide에서 볼 수 있듯이, 결국 coordinate transform이란 아래와 같다.
coordinate transformation이란, 결국 $x_c=PX_w$를 해결하는 것.
⇒ 결국 세상의 값(world coordinate)을 img coordinate으로 환산하는 것을 말한다.
⇒ 그리고, 이것이 img→world로 바로 변환되는 관계인가?
⇒ 그렇지 않다. img로 표현된다는 것은 중간에 카메라 혹은 그 역할을 해주는 것이 개입되기 마련이다.
⇒ 즉, 봐야할 것은 변환 행렬인 camera matrix이다.