Paper/Human

High-Quality Single-Shot Capture of Facial Geometry

침닦는수건 2024. 7. 19. 15:08
반응형

내 맘대로 Introduction

 

압도적인 썸네일...이게 2010년 수준인게 말이되나 싶을 정도로 압도적이다. 지금 기술력으로도 터무니없을 정도로 고수준의 복원 알고리즘. 디즈니에서 만들었고 코드 공개는 없다. 따라서 그냥 마스터 피스처럼 구경만 할 수 있는 논문.

 

핵심 아이디어는 1) 엄청 정확한 캘리브레이션 2) 스테레오 pair로 묶어서 엄청 정확한 disparity 계산 이다. 특히 2)에서 coarse-to-fine을 넘어서 coarse-to-fine-fine-fine으로 될때까지 0.01mm 움직이면서 튜닝하는게 압도적. 

 

물론 DSLR로 대충 찍은 12M 픽셀 정도가 아니라 초초고해상도 이미지가 받쳐주어야겠지만, NCC 만으로 이정도로 disparity 계산해낸 것이 대단하다. 

 

메모

카메라 세팅은 기본적으로 multi-view로 스캔하듯이 두는데, 2개씩 짝지어서 스테레오 세팅(rectification)으로 바꿀 거라서 화각 겹치는 정도가 많아야 하고, 되도록 카메라 각도 차이가 적어야 된다. 

핵심 energy term은 3x3 NCC로 계산하는 photo-consistency term과 disparity smoothness term이다. 





캘리브레이션은 실제 사람 머리 크기만한 sphere를 머리가 있을법한 위치에 두고 맞춤. sphere 표면에 왼쪽 그림과 같이 생긴 패턴을 불규칙하게 붙여서 triangulation 정확도로 맞췄다.

오른쪽 알고리즘은 어떻게든 정확하려고 Ransac까지 돌려가면서 triangulation 정확도 올린 방법. 




이 논문의 핵심은 단 하나다.

multiview camera들을 stereo pair로 묶어서 가면서 disparity 계산하는 기존 depth 계산 방식을 유지하되, 극한까지 잘하는 것이다.

최고 해상도가 1280 1280인데 (이미지 전체가 1280 1280이라는 뜻이 아니라 이미지 Crop한게 1280 1280이고 원본은 다른 것 같다. 1280 1280으로 모공 절대 못본다.)

처음 160 160 에서 disparity matching 해서 다음 320 320 에서 scope를 확 줄인다음 또 매칭, 올리고 또 매칭 하는 식으로 

coarse-to-fine으로 disparity matching을 한다. 
각 level에서 disparity 매칭은 기존 stereo와 똑같음. window size 3x3으로 고정하고 NCC를 매칭하는 방식

(여기서 3x3이 너무 작다고 할 수 있는데, 3x3 같이 작은 수준에서 매칭하기 때문에 디테일 업데이트에 유리하다. 조금만 변해도 값이 크게 변하니까)

2번 매칭 시도를 하는데, 

처음에는 그냥 매칭을 한다. 
-> 그다음 첫 매칭 결과를 smoothness 평가하고, smoothness가 튀는 결과는 초기화한 뒤, 이웃 disparity를 기준으로 다시 매칭함.
disparity 매칭할 때 재매칭 대상 선정을 디테일하게 더 보면 smoothness 말고 2가지 더 있음

1) smoothness 주변 neighbor disparities와 크게 다르지 않을 것. 1 pixel 미만으로 차이나야 함. 

2) uniqueeness : left to right, right to left matching 시 똑같아야 함 결과가. 

3) ordering disparity는 절대 왼쪽 오른쪽 이미지가 뒤집히는 방향으로 나올순 없다. 

왼쪽 이미지보다 오른쪽 이미지가 왼쪽에 있다고 나오면 당연히 잘못된 것.

위 1~3)에 해당하면 재매칭 시도.

disparity를 구했다는 말은 각 스테레오 세팅으로부터 backprojection 해서 Point cloud를 일단 만들겠다는 소리다.

point cloud to mesh는 어떻게 했냐? 

1) 각 시점 각 3d point마다 normal 계산 (depth map + camera pose가 있으니 가능)

2) 모든 시점 back projection 

3) 한 시점으로 다시 reprojection
한 픽셀에 2개 이상 3d point가 reprojection 되면, 해당 point 중 foreshortening angle이 큰 녀석을 제외 
-> 이게 무슨 뜻인지 잘 이해가 안가는데, 카메라 시점에서 보았을 때 카메라 ray랑 point normal이 90도에 가까울 수록 삭제했다는 뜻인듯 
-> 왜냐면 카메라 ray랑 평행할수록 surface가 카메라에 정면으로 잘보인 거니까 disparity 계산이 쉬웠을 것이고 신뢰도가 높았을 것.
-> 따라서 저 말은 point normal이 카메라 안바라보고 있고 다른데 쳐다보고 있으면 지웠다는 말인듯.
disparity 추정을 극한으로 끌어올리는 방법은 위 coarse-to-fine으로 NCC 매칭하는 것으로 끝나지 않았다. 

각 disparity map마다 photometric consistency로부터 오는 delta d, surface consistency로부터 오는 delta d 총 2개의 residual을 만들어 두고 업데이트를 한 번 더했다. 

대략 어떤 느낌이냐면, 

현 disparity NCC로 현 pixel을 보고 계산한 것인데, 이제는 양옆 disparity로 미루어보아 어떻게 조금 더 움직이면 주변 NCC까지 고려했을 때 더 정확할 지 찾아보는 것. 
우선 좌우 픽셀을 본다. (recitfication되어 있으므로 좌우만 보면 됨)

좌우 픽셀의 disparity로 좌우 NCC를 계산해보았을 때 현 위치 NCC보다 클 때, 중간일 때 작을 때에 따라 업데이트한다. 

만약 좌픽셀의 NCC가 제일 작다. disparity 오른쪽으로 이동

현 픽셀의 NCC가 제일 작다. 좌우 NCC로 weighted interpolation한 위치로 disparity 이동

우픽셀의 NCC가 제일 작다. disparity 왼쪽으로 이동.

또 다른 관점으로 NCC 상승을 위한 방향으로 disparity가 이동하는 것도 중요하지만 얼굴인만큼 smoothness가 잘 나와야 함.

따라서 좌우 disparity의 weighted sum 위치가 현 disparity가 되도록 하는 이동 delta도 계산함.
NCC 상승을 위한 이동 + smoothness 상승을 위한 이동을 어떻게 합치나?

weighted sum으로 합친다. 

smoothness weight는 사람이 지정한다. 

대신 NCC weight는 좌우 픽셀의 NCC를 고려해서 수식으로 계산

이렇게 하면 smoothness는 고정이기 때문에 NCC weight가 낮을 때는 자연스레 smoothness가 더 기능하도록 됨.
효과는 지렸다. 



이렇게만 해도 충분해 보이지만, 최최종 업데이트가 한 번 더 있다.

이제는 각 disparity map을 업데이트하는게 아니라 poisson recon한 뒤에 normal을 갖고 업데이트한다. 

현 3d point를 normal 방향으로 +- 0.1mm 씩 움직이면서 보정해보는 것이다. (0.1mm .....) normal은 고정

disparity 업데이트할 때랑 동일하게 NCC가 더 증가하고 smoothness가 더 증하도록 업데이트하는 것. 방식 동일.

여기서 mesoscopic 이라는 단어는 그냥 모공이 잘 보일 정도의 해상도 라는 뜻.

최최종 refinement의 목적은 앞선 stereo matching에 0.1mm 수준의 정말 정말 디테일한 보정을 시도하는 것 정도임.

앞선 NCC + smoothness 말고 하나 더 추가!


마이너한 보정은 모공이나 주름같은 수준일게 분명할테니, 보정의 시작은 이미지에 high pass filter를 씌우는 것으로 시작한다. 

mu(X) = high pass filter 씌운 이미지랑 안씌운 이미지랑 차이를 대충 의미하는 값.






high pass filter를 적정레벨로 잘 적용하면 spatially bigger skin features (여기선 점을 말하는 것 같다... 점이 크다니...)는 자연스레 업데이트에서 배제되므로 정말 모공이나 주름 같이 디테일만 업데이트에 관여할 수 있도로 된다고 한다. 

다루고자 하는게 모공, 주름이라 점이 크다고 하는 듯.

앞선 mu를 갖고 weighting + 주변 3d point와 weighted sum을 하면 현 3d point가 normal 방향으로 얼마나 움직여야 하는지 계산.

이건 진짜 1px 단위에서 변하는 색깔을 잡아낼 수 있어야 하므로, 이미지 해상도가 어마어마 해야될 듯. (알아보니 1510만 화소다...)
X의 업데이트는 그럼 NCC + smoothness, mesoscopic 3개의 weighted sum으로 최종 결정됨.





1510만 화소 그대로 쓰면 이정도까지 되는구나.... 어마어마 하네.


DSLR 아니고 일반 스테레오 카메라 입력으로 돌려도 준수한 수준까진 되나 보다. 
반응형