작년 ICCV2025 때 포스터를 보기도 했고 그 이전에도 arxiv 논문으로 먼저 읽어봤던 FaceLift 가 있었다. 개인적으로 Adobe에서 쓴 논문이기 때문에 퀄리티에 대한 의심은 없었고 코드가 공개되길 내심 기대했었는데 반갑게도 공개가 됐더라. 얼굴 정면 이미지를 입력하면 Multiview diffusion으로 정해진 시점의 6장 이미지를 만들어 내고, 이 multiview image + camera pose가 뒷단의 GS-LRM 모델에 들어가 pixel 마다 3DGS를 예측하는 구조다.

3DGS를 최적화로 수렴시켜서 찾아내는 것보다 pixel마다 prediction하는 구조이기 때문에 3DGS candidate가 월등히 많아 디테일을 표현하기에 굉장히 유리한 모양이다. 그래서 위 그림처럼 수렴만 잘한다면 진짜 높은 품질을 기대할 수 있다.
내가 한 것
GOF rasterizer
최종 결과물을 3DGS로 내뱉는 feed-forward 방식을 요즘 자주 보이는 컨셉인 것 같은데 나는 이걸 조금 더 확장해보고 싶었다. 개인적으로 3DGS 결과물에서 가장 아쉬운 것은 mesh 뽑기가 어렵다는 점. 2DGS 같은 컨셉이 있긴 결국 surfel같은 얇은 원판으로 구현하는 것이기 때문에 noisy하고 뒷단에 TSDF+Marching cube가 붙는 구조이기 때문에 후처리 단에서 또 정확한 geometry를 뽑기가 애매하다. 이 와중에 내가 발견한 것은 Gaussian opacity field.
https://github.com/autonomousvision/gaussian-opacity-fields
GitHub - autonomousvision/gaussian-opacity-fields: [SIGGRAPH Asia'24 & TOG] Gaussian Opacity Fields: Efficient Adaptive Surface
[SIGGRAPH Asia'24 & TOG] Gaussian Opacity Fields: Efficient Adaptive Surface Reconstruction in Unbounded Scenes - autonomousvision/gaussian-opacity-fields
github.com

2024 SIGGRAPH 논문인데 volume rendering 테크닉을 3DGS에 가져온 논문이라 볼 수 있다. 3DGS의 모양을 바꾸는 구조가 아니라 3DGS 렌더링 수식을 교체해서 3DGS가 volume density와 color를 동시에 표현하는 구조다.
나는 이 논문이 다른 컨셉들과 궤를 달리한다고 생각했다. 이론적으로 3DGS가 surface에 맺히도록 유도한다는 점이 매우 합리적으로 보였고 실제로 결과도 탄탄했다. 그래서 나는 개인적으로 mesh를 추출하는 컨셉이 아니어도 이렇게 3DGS가 volume density와도 타이트하게 결합된 형태로 수렴하도록 만드는 것이 정석이 되어야 하지 않을까 생각했다.
그래서 나는 FaceLift를 다시 처음부터 학습시키는데 뒷단의 vanilla gaussian rasterizer를 gaussian opacity field rasterizer로 교체해서 학습해보았다. 구조적으로는 완전 동일하지만 결과물 3DGS가 이제는 이미지 렌더링용 뿐만 아니라 geometry에 더 coupled형태로 나오는 걸 기대했다.
Synthetic Dataset

데이터는 직접 제작했다. 일단 오픈소스를 긁어모으는 것은 당연히 했고 nphm, th2.1, rp, faceverse를 포함한 내가 직접 만든 데이터셋 16000개를 추가했다. ([Dataset 제작] Polygom8K8K 데이터셋 만들기 polygom8k8k_ext라고 8000개 더 있다.)

FaceLift 학습 포맷에 맞춰서 데이터를 전처리하는 과정이 매우 까다로웠는데, 다행히도 내가 이전 논문 작업으로 정리해둔 파일들을 활용해서 3일 정도 걸려 처리할 수 있었다. FLAME을 미리 다 피팅해두었기 때문에 FLAME을 기준으로 scale, rotation, translation을 normalize한 뒤에 이미지를 렌더링해서 (image/mask/depth + camera pose)를 만들어둘 수 있었다.
참고로 FaceLift 데이터를 뜯어보니 학습할 때 사용한 카메라 포즈 입력이 매우 단조로웠다. (앞의 Multiview diffusion model이 자유로운 카메라 포즈에 반응하도록 학습하는 것 자체가 너무 어렵기 때문에, 고정된 카메라 포즈에 맞추어져있고 뒷단에 이어지는 GS-LRM을 그러면 굳이 다양한 카메라 포즈를 커버하지 않아도 되기 때문에 이렇게 했을 것 같다. ) 그래서 인지 카메라 포즈가 조금 심하게 틀어지면 reconstruction이 잘 안되는 문제를 발견했었다. 이 문제를 해결하고 싶어서 나는 학습 데이터를 만들 때 azimuth, elevation augmentation을 엄청 크게 해서 넣어줬다.
Real Dataset


개인적으로 이 FaceLift를 재학습하면서 하나 더 개선해보고 싶은 점이 다양한 헤어스타일 커버력이었다. Synthetic 데이터로 sim-to-real gap을 커버해서 학습하는게 아무리 요즘 컨셉이라고 하지만 full synthetic으로 아직 따라잡기 어려운 영역이 hair style의 다양성이다. synthetic으로 hair를 만든다는 것이 3D 디자이너를 엄청나게 갈아넣어야 하는 영역이기 때문에 synthetic hair asset은 그리 다양하지 않고 실제 헤어스타일을 그렇게 잘 담아내지도 못한다. FaceLift를 학습할 때도 아무리 Adobe 가 학습 데이터를 제공했다고 해도 이 점은 부족했을 것이다.
나는 실제 사람 hair 데이터를 대규모로 넣고 싶었다. 그래서 시도한 것이 K-hairstyle 데이터셋의 활용이다. K-Hairstyle 데이터셋은 개인적으로 굉장히 잘 만든 데이터셋이라고 생각하는데 헤어스타일이 겹치지 않게 대규모로 포함되어 있다. NIA 과제로 긁은 데이터겠지만 이 정도로 성실하게 모았다는 것에 감사하다. 이 데이터에는 미용실에서 사람 머리를 뱅글뱅글 돌면서 카메라로 촬영한 이미지들이 저장되어있다. 카메라 파라미터는 하나도 없고 그냥 이미지꾸러미일 뿐인데 나는 이걸 전처리해서 3D 데이터로 만들었다.
1. 일단 모든 샘플을 Metashape을 이용해서 SfM+MVS을 돌렸다. (같은 카메라로 촬영한 데이터가 많았기 때문에 해상도가 같으면 shared intrinsic을 사용하도록 설정했고 뱅글뱅글 돌면서 촬영했기 때문에 sequential matching으로 풀리도록 설정했다.)
2. SfM+MVS 결과를 수작업으로 성공 실패 샘플을 분리. (몇천개 안되지만 직접 보는데 한 6시간은 걸린 듯 하다.
3. 초상권 문제를 풀기 위해서 얼굴 가려진 영역을 insert-anything 을 사용해서 inpainting했다. (비용 안받는 diffusion model 공개해줘서 너무 고맙다.)
4. inpainted image + camera pose + WarpHE4D_ReFLAME 사용해서 FLAME을 피팅
5. fitted FLAME을 기준으로 카메라 포즈를 normalization해서 FaceLift 포맷에 맞춰 정리.

결과적으로 많은 샘플들이 전처리의 각 단계에서 실패해서 제외되었지만 총 3001개의 hair style 데이터를 확보했다. 규모는 작지만 각각 샘플이 어느 synthetic 데이터로도 만들기 어려운 실제 헤어스타일을 담고 있기 때문에 가치가 엄청 큰 데이터라고 생각한다.
(내가 만들었지만 생각보다 엄청 고퀄리티의 데이터가 만들어졌으니 혹시 필요하면 저에게 요청하시길)
Training and Results
문제 1 : multi-surface geometry로 수렴하는 문제
GOF rasterizer로 교체해서 학습하면 잘 될 줄 알았으나 생각보다 순탄치 않았다. GOF rasterizer 코드를 뜯어보면 내부에 filter_3d라는 코드가 존재하는데 이게 현재 3DGS의 scale과 opacity를 카메라 시점의 픽셀 크기에 걸맞도록 변환하는 후처리를 한다. 쉽게 말해 카메라가 가까우면 크기를 키워서 최소 한 픽셀에는 꽉차게 수정하는 방식이다. 이 필터를 켜둔 상태로 학습을 하니까 렌더링 이미지 퀄리티는 점점 높아지는데 3DGS 위치를 보니 여러 겹으로 보이도록 수렴을 했더라.
원인은, 3DGS 위치가 surface와 멀어지더라도 filter_3d 힘으로 한 번 조정되면 이미지는 그럴듯하게 렌더링할 수 있으니 잘못 수렴하는 문제였다. 이게 원래 방식대로 최적화 프레임워크에서는 filter_3d가 조건처럼 적용돼서 안맞는 3DGS가 도태되고 새로 알맞게 생성되기 때문에 문제가 없는데 prediction 프레임워크에서는 filter_3d가 편법으로 적용돼서 제대로 예측을 못하더라.
이 문제를 해결하기 위해 고민을 해보다가 결국 효과가 있는 것은 다음과 같았다. 첫째, filter_3d를 끄고도 렌더링을 한다음 auxiliary loss로 추가해주는 것이다. 다시 말해 filter_3d를 on/off 로 총 두 번 렌더링한 다음 두 결과 모두에 loss를 걸어주는 dual rendering 체계로 학습하면 해결됐다. 둘째, GOF 원래 논문에서 사용하던 distortion loss랑 depth_normal_loss를 그대로 편입하는 것이다. distortion loss가 ray 당 dominant gaussian을 1개만 만들도록 강제하기 때문에 multi-surface 효과가 줄어드는 듯 했다. depth_normal_loss는 드라마틱하진 않지만 mesh surface 뽑아봤을 때 미약하게 나마 보정효과가 있어서 추가했다.
문제 2 : noisy mesh surface
문제 1을 파훼하면서 이제 3DGS가 geometry와 잘 맞아 떨어지고 Novel view synthesis도 잘해내는 것을 관찰했는데 최종적으로 내가 FaceLift를 FaceLift+로 확장하면서 달성하고 싶은 mesh extraction이 아쉬웠다. 더 이상 이론적 문제는 하나도 없지만 mesh가 너무 noisy했다. 이건 수학 모델과 코드의 문제가 아니라 현 방식에서는 이게 당연한 결과라는 결론이었다. 그렇지만 아쉬웠다.
그래서 내 결론은 synthetic dataset으로부터 smooth surface를 만들도록 prior를 학습하도록 유도하는 것이었다. GOF 수식을 따라 volume density + color를 표현하도록 3DGS를 학습시키지만 이왕이면 smooth surface로 만들도록 하면 조금 깔끔한 mesh가 나오지 않을까 기대했다.
추가한 것은 단순하게도 depth GT supervision loss였다. synthetic dataset은 mesh가 존재하니까 여기서 만든 depth GT를 가지고 직접 rendered depth와 l1 loss를 추가했다. 3DGS 위치를 강하게 보정하는 loss인 셈인데 smooth GT surface로 계속 강제당하다보면 조금 prior를 배우지 않을까 싶었다. (+depth smoothness loss를 약하게 추가도 했음 TV loss 같은 컨셉으로)
이렇게 추가해주고 학습하니 놀랍게도 엄청나게 향상된 결과를 보여줬다.




결과적으로 매우 만족스럽다. FaceLift와 구조는 완벽히 동일하기 때문에 모델 교체만으로 이런 결과를 얻을 수 있다. 앞단의 Multiview diffusion model은 FaceLift 것을 그대로 가져다 쓰면된다.
Conclusion
단순한 확장으로 시도해봤는데 생각보다 결과가 너무 깔끔하게 나와서 좋다. GOF가 엄청 좋은 논문이라는 것의 증명을 나 스스로 했다는 것에 뿌듯하고 이런 컨셉의 확장이 다른 분야에서도 분명 의미있겠다는 확신이 들었다. 누군가도 이 생각에 공감해서 좋은 영감으로 새로운 연구를 할 수 있었으면 좋겠다.
이 모델을 이용해서 이미지로부터 대규모 3DGS+mesh를 뽑아낼 수 있을 것 같아서 이걸로 데이터를 좀 잔뜩 만든 다음 후속 연구를 하나 해봐야 겠다.
'Footprints > Output.log' 카테고리의 다른 글
| [Template mesh model 제작] METHA : Meta's topology-based (Ava-256, Multiface) Template model for Head Avatar (0) | 2025.05.15 |
|---|---|
| [Dataset 제작] Polygom8K8K 데이터셋 만들기 (0) | 2025.04.21 |
| [Dataset 제작] Polygom2K2K 데이터셋 만들기 (구. 2K2K 데이터셋) (0) | 2025.04.21 |
| [Model 제작] Face UV tracker (0) | 2025.01.19 |
| Curriculum Vitae (2024.07.28 updated) (0) | 2024.07.28 |