* 본글의 모든 그림, 영상은 논문의 본문 및 발표영상에서 가져왔습니다.
상당히 오랜만에 논문의 내용을 정리해봅니다.
뭐 이런저런 이유로 오늘은 좀 다른 내용의 논문을 들고 왔습니다.
요즘 가장 핫한 분야 중에 하나인 NeRF(Neural Radiance Fields)에 관련된 논문인데요!
본격적인 내용으로 들어가기 앞서 아주 간략하게 NeRF에 대해서 알아보도록 하겠습니다.
우선, NeRF의 궁극적 목표는 view synthesis입니다.
하나의 물체([그림 1]에서는 드럼)를 여러 각도에서 동시에 촬영한 이미지 n장을 입력 데이터로 사용합니다. 그 이미지들을 이용해서 이미지에 주어지지 않은 새로운 각도에서의 동일 물체의 이미지를 만들어내는 것이죠.
이 분야에 대해 처음 들어보시는 분들은, 이게 왜 어려운가, 그냥 중간 값을 interpolation 하면 되는 것 아니냐, 하실 수 있겠지만, 실제로는 굉장히 어려운 작업으로 이 논문 이전까지는 이정도 퀄리티의 결과를 얻어내는 것이 상당히 어려웠습니다.
위의 그림이 NeRF 논문의 전반적인 구조입니다.
간략하게만 설명드리자면, 다양한 각도에서 들어온 이미지들의 viewing direction을 구하고, 그 구해진 각도에서의 ray를 쏜다고 가정합니다. 그때 3d 공간 상에서 얻어진 point sample들([그림 2]에서 검은 점들)의 값을 더하면 앞의 이미지를 만들 수 있겠죠. 그렇다면 그 점들의 실제 rgb값과 density값이 무엇일지 MLP모델을 통해 학습하면, 실제 모델의 해당 각도에서의 rgb값이 무엇인지 알게 되는 것입니다.
이정도의 설명으로는 이 논문에 대해서 쉽게 이해하시기 어려우실 것 같아, 아래 참고하실만한 한국어 설명 영상 링크 첨부합니다.
오늘 제가 설명할 논문의 경우에 NeRF에 대해 충분히 알고 있어야 이해가 가능하시니, 꼭 영상이나 논문 읽어보시고 아래의 내용도 함께 보시길 추천드립니다. (혹시 시간이 된다면, 의지가 생긴다면, 저도 NeRF에 대해 설명 글을 올려보겠습니다. 근데 주로 잘 안 생기더라구요...ㅎㅎ)
자 그럼 드디어, Nerfies에 대해서 설명으로 넘어가보겠습니다!
일단, 이 논문의 경우 아직 publish가 되지 않은 것으로 보입니다! (ICCV에 제출된 논문이라 아직 결과가 나오지 않은 것인지, 아님 다른 곳에 제출했는데 reject된 것인지, 잘 모르겠어요.) ICCV 2021에 퍼블리시 되었습니다!!
지금 NeRF 분야가 워낙 핫하다 보니 비슷한 컨셉을 가진 논문들이 동시다발적으로 미친듯이 나오는데요.
이 논문도 유사한 컨셉을 가진 논문이 3개가 거의 동시에 업로드 되었습니다.
이 글의 후미에 한번 3개의 논문이 어떤 차이점을 가지는지 간략하게 설명드려보도록 하겠습니다.
이 논문의 경우 설명드릴 부분들이 너무 많아 두개의 글로 나눠 올리도록 하겠습니다.
논문의 1편에서는 알고리즘의 전반적인 부분에 대해 설명드리고, 2편에서 이 모델을 학습시키기 위해 어떤 regularization term을 추가했는지, 결과는 어떠한지, 논문간의 차이점에는 어떤 것이 있는지 설명드리겠습니다.
NeRF 논문 전문: https://arxiv.org/pdf/2003.08934.pdf
NeRF 설명 영상(한글): https://www.youtube.com/watch?v=zkeh7Tt9tYQ
NeRF 발표 영상: https://www.youtube.com/watch?v=JuH79E8rdKc
[출처] Mildenhall, Ben, et al. "Nerf: Representing scenes as neural radiance fields for view synthesis." European Conference on Computer Vision. Springer, Cham, 2020.
Nerfies 논문 전문 : https://arxiv.org/pdf/2011.12948.pdf
Nerfies 프로젝트 홈페이지 : https://nerfies.github.io/
[출처] Park, Keunhong, et al. "Deformable Neural Radiance Fields." arXiv preprint arXiv:2011.12948 (2020).
<개요>
이 논문의 경우 기본적인 NeRF와는 다르게 좀 더 어려운 경우에 대해서 해결을 해보고자 알고리즘을 제안을 했습니다.
위의 영상에서 보시는 바와 같이, 움직이는 물체나 사람의 영상을 촬영하고, 그때 얻어진 frame들을 입력 값으로 사용합니다. 즉, 이때 여러가지 문제점이 발생을 하는데요.
1. 사람이 아무리 가만히 있으려고 해도! 움직임이 발생한다.
: 이게 가장 키포인트입니다.
기존의 NeRF의 경우에는 움직임이 없는 물체를 동시에 여러장의 이미지를 찍어 만들었기 때문에 움직임이 존재하지 않았습니다. 즉, 어떤 이미지를 보더라도 동일한 것을 보고 있는 것이죠.
반면, 이 논문의 경우 우선 동시에 촬영된 이미지들이 아니기 때문에 시간 축에 대한 변화가 생깁니다. 사람이 카메라를 들고 영상을 찍게 되면 아무리 가만히 있으려고 해도 움직임이 발생하게 되죠. 이렇게 되면 입력 이미지들 간에 변화가 생겨버립니다. 이러한 부분이 NeRF를 그대로 돌리게 되면 결과를 망치게 하는 문제점이었습니다.
2. 실제 사람이 갖고 있는 재질에 어려움이 존재한다.
: 사람을 촬영한다고 할 때, 다양한 재질이 함께 포함이 되는데요. 예를 들어, 머리카락, 안경과 같이 매우 얇은 물체들, 귀걸이 같이 빛나는 물체들이 함께 포함되게 됩니다. 빛을 반사하는 성질이 강한 물체나 머리카락 같이 매우 얇은 물체들은 사실 랜더링 할 때 매우 난이도를 높혀주는 점들이 됩니다.
그렇다면, 저자는 이러한 문제들을 어떻게 해결했을지 한번 그 구조에 대해 알아보도록 하겠습니다.
<알고리즘 설명>
전반적인 알고리즘의 구조는 다음과 같습니다.
간략하게 말씀드리자면,
1. 움직이는 물체의 영상을 canonical space로 옮긴다.
2. 옮겨진 좌표 값들을 이용하여 nerf를 계산한다.
즉, 먼저 움직이는 물체를 하나의 표준화된 공간으로 옮기면 움직이는 물체들도 하나의 geometry 정보를 갖는 공간에서 볼 수 있겠죠. 그 다음에 nerf를 계산하는 방식입니다.
하나하나 좀 더 자세히 살펴보겠습니다.
1. Preprocessing
우선, 네트워크에 입력 값으로 사용할 이미지를 얻어내야합니다.
(a) 일련의 동영상에서 얻어진 이미지들 중에서 흐릿한 이미지를 먼저 제거해줍니다.
(b) 이렇게 얻어진 이미지들은 SFM(Structure From Motion)을 이용하여 각각 이미지의 viewing direction을 구하고, background를 분리합니다. (이게 어떻게 동작하는지에 대해서는 또 쓸 내용이 한바가지이므로... 우선 그냥 그렇구나 하고 넘어가주세요. 궁금하신 분들은 설명이 담긴 블로그를 링크로 달아두겠습니다. 읽어보셔도 좋습니다!)
2. Neural Deformation Fields
먼저, deform된 물체, 즉, canonical에서 움직임이 발생된 채로 캡쳐된 이미지의 물체를 canonical space로 옮기는 네트워크를 통과시킵니다.
즉, nerual deformation fields를 통과하고 나면 [그림 5]에서 보여지는 것과 같이 canonical space로 값이 옮겨가는 것입니다. 보시는 것과 같이, 사람의 포즈만 살짝 바뀌는 것이죠.
어떤 방식으로 동작하는지 자세히 살펴보겠습니다.
먼저, 앞서 처리된 이미지에서 ray casting을 진행합니다. 그래픽스에서 'ray casting을 한다'는 것은 가상의 빛을 쏜다고 가정하고 그 빛에 부딫히는 point들을 찾는 것입니다.
실제로 우리가 어떤 물체를 볼 때 그 물체의 실질적 rgb 값을 보는 것이 아니라 중간에 부딫히는 모든 입자들의 값을 보는 것이죠. 이미지가 찍힐 때도 마찬가지입니다! 즉, 현재 우리는 이미지에 찍힌 어떤 값이 카메라와 동일한 위치에서 봤을 때 어떤 입자들이 어떤 구조를 갖고 있는지를 알면, 3d의 geometry를 알 수 있는 것이죠. (이것도 자세히 적으려면 한바가지랍니다...)
그렇게 그 ray를 따라 존재하는 point들 중 uniform하게 몇개의 point를 고릅니다.(이 sampling하는 방식에 대해서는 NeRF 논문에서 자세히 설명하고 있습니다. 우선 여기선 uniform하게 추출했다 가정하겠습니다ㅎㅎ)
Sampling된 point들의 위치 값(x,y,z)를 입력 값으로 사용하여 네트워크를 학습시킵니다. 그 네트워크의 구조는 기존의 NeRF와 동일한 단순 MLP구조입니다. output으로는 이 점이 실제 canonical space에서 위치하는 좌표로 움직이려면 얼마나 가야하는지에 대한 offset 값이 나오게 됩니다. 즉, 해당 offset 만큼 움직이면 해당 point가 canonical space에서 어디에 위치하는지를 알 수 있는 것이죠.
이때! 입력 값에 latent deformation code를 함께 넣어줍니다. 이 code가 갖고 있는 정보는 해당 object에 대한 움직임 정보를 갖고 있습니다.
실제로 정적인 물체가 아닌 동적인 물체의 input 이미지에는 많은 variation이 있습니다. variation이 크면 클 수 록 학습은 어려워지죠. 그래서 애초에 이 이미지에서 어떤 움직임에 대한 정보(rotation, translation 등)를 함께 네트워크에 넣어준다면 학습이 조금 더 용이해질 수 있겠죠? 네트워크에서 자동적으로 혹은 임의적으로 해당 정보를 지워낼 수 도 있으니까요! (이 코드에 대한 아이디어는 NeRF in the wild 논문에서 먼저 제안 되었습니다.)
이 코드는 GLO(Gernerative ) 에서 차용하여 구한다고 합니다. (이 논문은 제대로 읽어보지 않아 구체적으로 어떻게 구성되어있는지는 코드 리뷰를 한번 해봐야할 것 같아요.ㅎㅎ 알게 된다면 업데이트 하겠습니다)
코드가 어떻게 동작하는지는 위의 [그림 6]에서 확인할 수 있습니다. deformation code를 변경해가면 두 이미지 사이의 움직임에 대해 부드럽게 interpolation 된 이미지를 얻어낼 수 있습니다. 즉, deformation code가 움직임에 대한 정보를 담고 있다는 것을 보여주는 것이죠.
이렇게 해서 정리하자면, sampling된 point의 좌표와 deformation code가 concat 되어 입력값으로 사용되고, MLP를 통과해 나온 offset을 이용하여 canonical model의 위치로 옮겨가게 됩니다.
3. Estimating RGB color and density per points
이제 옮겨진 좌표에서의 일련의 point set들을 NeRF와 똑같은 구조를 갖는 template NeRF에 넣어 특정 카메라 방향에서의 해당 포인트의 RGB 값과 density값을 찾아냅니다.
위의 수식에서 최종 모델의 input이 무엇인지 보여줍니다.
T인 deformation field에서 얻어진 옮겨진 좌표와 카메라의 viewing direction, 그리고 appearance code를 이용합니다.
즉, viewing direction에서 봤을 때의 이미지에 랜더링 된 rgb값, density값을 찾아내는 알고리즘입니다.
이때 이전에 설명드린 deformation code와는 달리 appearance code는 이미지 자체의 variation을 줄여줍니다. 이미지를 동시에 촬영한 것이 아니기 때문에 살짝씩 이미지에 다른 부분이 생길 수 있습니다. 광원의 방향이나, 그림자 등과 같이 frame간에 발생할 수 있는 variation에 대한 정보를 미리 appearance code를 통해 구합니다. deformation code와 동일하게 학습할 때 모델에 함께 넣어 자동적으로 학습을 돕도록 하는 것이죠.
이렇게 얻어진 rgb와 density 값을 이용해 해당 뷰에서의 해당 좌표의 이미지 상의 값을 구할 수 있습니다. 최종 loss는 구해진 값과 실제 이미지에서의 pixel 값을 MSE loss를 통해구합니다.
<사족>
아직 설명드릴 부분이 많은데, 우선 여기서 1편을 마치도록 하겠습니다.
컨셉적인 부분에 대해서 궁금하신거라면, 여기까지 보시면 얼추 다 이해하신거랍니다...ㅎ
구체적으로 어떤 트릭들이 들어가는지 알고 싶으신 분들은 2편까지 읽어주세요!
Nerfies 2편 : https://reading-cv-paper.tistory.com/entry/archive-Nerfies-Deformable-Neural-Radiance-Fields-2
(사실 제 전문 분야가 아니라, 이해하고 완전히 체득하지는 못한 것 같아요.)
궁금하신 점이나, 틀린 부분이 있다면 언제든지 댓글 남겨주세요!
감사합니다.