논문 요약

[CVPR-2018]V2V-PoseNet: Voxel-to-Voxel Prediction Network for Accurate 3D Hand and Human Pose Estimation from a Single Depth Map

논문읽어주는석사생 2020. 5. 28. 13:50

* 본글의 모든 그림은 논문의 본문과 저자의 발표 자료에서 가져왔습니다.

 

정말 너무너무 오랜만에 새로운 논문을 들고왔습니다. 이런 완성도 낮은 글을 누가 찾아볼까 생각했는데, 생각보다 틈틈히 많은 분들이 방문해주셔서 감사한 마음도 있고, 부끄러운 마음도 드네요ㅎㅎ

 

제가 잠시 포스팅을 하지 않는 동안, 졸업을 하고, 취직을 하게 되면서 약간(?) 연구 주제가 바뀌게 되었습니다. 오늘은 그 동안 리뷰했던 것과 달리, pose estimation 분야에서의 논문에 대해 소개하고자 합니다. 이전까지는 3d skeleton based action recognition과 관련된 논문이었는데, 오늘은 그 알고리즘들의 기반이 되는 3d skeleton을 depth 영상에서 어떻게 추출하는가에 대한 내용입니다.

 

그 중에서도 오늘 리뷰할 논문은 'V2V-PoseNet: Voxel-to-Voxel Prediction Network for Accurate 3D Hand and Human Pose Estimation from a Single Depth Map'로 한장의 depth 이미지에서 사람의 손의 포즈(skeleton의 위치)를 추출하는 알고리즘에 대해 제안하는 논문입니다. 논문 내용이 그렇게 어렵지 않고, 서울대에서 나온 논문이라, 한국어 동영상 설명 자료도 있어 링크로 함께 첨부해둘테니, 이해가 안되시는 분들은 참고해주세요. 

 

논문 전문 : https://arxiv.org/pdf/1711.07399.pdf

[출처] Moon, Gyeongsik, Ju Yong Chang, and Kyoung Mu Lee. "V2v-posenet: Voxel-to-voxel prediction network for accurate 3d hand and human pose estimation from a single depth map." Proceedings of the IEEE conference on computer vision and pattern Recognition. 2018.

 

한국어 발표 영상 : https://www.youtube.com/watch?v=Y8ce9mEZGLw

 

 

<개요>


사람의 손의 pose 혹은 전체 body의 pose를 추출하는 방식에는 크게 4가지의 방향성이 존재합니다. 어떤 input data를 사용해서 어떤 output을 내느냐에 따라 달라집니다.

[그림 1]

결과적으로 저자는 [그림1]의 (d)에서 보여지는 것처럼 depth를 voxel로 표현한 3d 공간에서 cnn을 이용해 feature를 추출하고 좌표로 위치를 표현하는 것이 아닌, 3d voxel상의 heatmap으로 보여줍니다. 따라서 V2V(Voxel to Voxel)이라는 이름이 붙었죠. 

 

저자가 이 방식을 선택한 것은 기존의 방식에서의 분명한 단점을 해결하기 위함입니다. 

 

첫번째 문제점은 perspective distortion에 대한 것입니다.

[그림 2]

[그림 2]에서 보여지는 것과 같이, 3d 상에서의 어떤 특정 물체는 2d 이미지로 옮겨지면서 perspective distortion의 문제가 생깁니다. 왼쪽의 손의 동작이 어떤 위치에서 사진을 찍느냐에 따라서 가운데의 이미지처럼 다양한 모습으로 나타날 수 있습니다. 이 데이터를 normalize하지 않고 그대로 사용하게 되면, 네트워크가 한번 자동적으로 왜곡을 지워서 실제 손 모양이 어떤가를 유추해야하기 때문에 좀 더 어려워지고 학습이 잘 안될 가능성이 생깁니다. 이 논문의 저자는 이러한 문제를 없애기 위해 V2V Posenet 알고리즘을 제안했죠.

 

두번째로는 기존의 방식은 일대일 mapping이 되지 않는다는 문제점이 존재했었습니다. 일단 3d상의 어떤 값들이 2d depth 이미지로 한번 mapping이 된 것을 사용해왔기 때문에 linear하게 mapping이 되지 않았습니다. 이 부분이 학습을 하는데 있어 직관적인 부분을 약화시킨다고 생각할 수 있습니다. 

 

구체적으로 이러한 단점들을 어떻게 극복했는지 좀 더 자세히 알고리즘을 살펴보도록 하겠습니다.

 

 

<알고리즘 설명>


[그림 3]

 

알고리즘의 전반적인 흐름은 다음과 같습니다.

 

1. 2d depth 이미지를 voxelization을 통해 3차원의 voxel로 표현합니다.

2. 표현된 voxel을 3d cnn과 encoder-decoder 구조를 이용하여 feature를 추출합니다.

3. 추출된 feature를 이용하여 3d heatmap을 만들어 각 관절이 어디에 위치하는지 표시합니다.

 

구체적으로 이러한 방식들이 어떻게 구현이 되는지 살펴보도록 하겠습니다. 

 

1. Refining target object localization / Generating input of proposed system

먼저, 간단한 네트워크를 통해 posenet에 넣고자 하는 입력 부분을 추출해냅니다. 사람의 손 모양을 찾고 싶은데 다른 부분의 depth 값들이 입력되지 않도록 막아주는 것이죠. 기존에는 이렇게 원하는 부분만 crop하기 위해서 특정 절대적인 depth를 정해서 나머지 부분들을 thresholding해주거나 위치를 기반으로 잘라냈습니다. 

 

[그림 4]

하지만 이러한 경우 [그림 4]의 왼쪽과 같이 중심이 제대로 맞지 않아, crop한 부분에 원하는 부위의 전부가 들어가지 않는 경우가 발생하게 됩니다. 이럴 경우 아무래도 모델의 성능에 영향을 미칠 수 밖에 없겠죠....

 

본 논문에서는 다음과 같은 현상을 [그림 4]의 오른쪽 사진처럼 보정하기 위한 방식을 딥러닝을 통해 해결하고자 제안합니다. 

[그림 5]

[그림 5]에서 처럼 먼저 기존의 방식을 통해 특정 부분을 잘라내고 해당 부분의 center를 찾습니다. 해당 부분을 2d depth이미지로 변환한 후 위의 사진에서 나와있는 모델 구조에 입력 값으로 넣어, 최종 결과로 center의 위치가 옮겨가야하는 offset 값을 받습니다. 이렇게 보정된 center를 중심으로 정해진 크기만큼 crop을 합니다. 

 

이렇게 찾아낸 손 부분을 V2V posenet에서 입력값으로 사용할 voxel 형태로 바꿔줍니다. 기존에 입력으로 받았던 이미지는 2d depth 이미지, 즉 [그림 5]에서 가장 왼쪽에 있는 사진이었는데요. 해당 이미지를 실제 depth 값을 기반해서 3d 상으로 값을 옮겨줘야합니다. 특정 voxel  공간에서 해당 좌표에 손의 부분이 위치하면 1, 그렇지 않으면 0으로 채워줍니다.

 

2. V2V-PoseNet

이제 입력으로 넣을 데이터를 만들었으니, 본격적으로 모델을 학습시켜보도록 하겠습니다.

 

전반적인 구조는 [그림 3]에서 보이는 바와 같습니다. 크게 4종류의 블럭이 존재합니다.

 

1. volumertic basic block 

2. volumetric residual block

3. volumetric downsampling block

4. volumetric upsampling block

 

순서대로 흐름을 쭉 보자면, volumetric basic block을 통해서 먼저 feature를 추출하고 downsampling을 합니다. 후에 residual block을 통해 유용한 local feature를 추출하고, 다음으로 encoder-decoder 구조를 통해 skeleton의 위치로 추정되는 곳에 heatmap을 그리게 됩니다. 

 

encoder에서는 spatial의 크기를 줄이면서 channel의 개수를 늘려감으로써 feature를 압축해갑니다. 추출된 최종 feature를 통해 새로운 voxel map을 decoder에서는 그리게 됩니다. 

 

해당 결과물과 실제 ground truth의 joint의 위치와의 차이를 계산해서 loss을 업데이트 해주는데요. 이때 가우시안 함수를 사용하여 확률에 대해 계산할 수 있도록 해줍니다. 즉, 정확한 위치를 결과물로 내놓을 수 록 loss값이 줄어들게 하는 방향으로 학습이 되는 것입니다. 구체적인 수식은 논문에 나와있으니 참고해주세요.

 

 

<사족>


이 논문에서 주장하는 큰 장점이 두가지가 있습니다.

 

1. voxel to voxel이기 때문에 왜곡없이 linear하게 학습할 수 있어, 성능 향상에 도움이 된다.

2. 마지막 단에서 coordination 좌표로 결과가 나오는 것이 아니라, voxel의 heatmap으로 나오기 때문에, FC layer가 없고 convolution 연산으로 끝나게 됩니다. 이때 오는 메모리, 즉 computational cost적으로 많은 이점이 있습니다.

 

이러한 장점 덕분에 실제 논문에서 결과 사진들을 보면 정말정말 관절들을 잘 찾습니다. occlusion 된 부분들도 잘 찾고, 심지어 손 뿐만 아니라 사람의 body에 대해서도 엄청 잘 찾습니다. 그리고, 계산량이 적기 때문에 저자가 말하기를 titan 1080 gpu한개에서 약 30fps정도의 속도로 실시간으로 검출하는 것도 가능하다고 하더라구요. (제가 실험해봤을때는 25fps 정도 밖에 안나오긴 했습니다...)

 

 

언제나 그렇듯 아쉬운 점은 있습니다.

사람의 body skeleton을 찾는 것에 대한 실험으로 사용한 dataset 같은 경우, frame 단위로 보자면 상당히 많은 data를 학습하는데 사용했는데요. 하지만, 동영상에서 보면 보통 바로 붙어있는 frame들은 거의 동작이 유사하죠. 실제로 학습할때도 유사한 data들이 굉장히 많이 사용된 것 같습니다. 따라서, 학습이 잘되긴 했는데 거의 그 dataset에 overfitting됐을 가능성이 큽니다. 실제로 제가 다른 test data들을 넣어서 결과를 봤을때도 조금 흔하지 않은 동작들에서는 에러가 나더라구요. 

 

+추가적으로 실제 구현되서 공개된 코드가 있어서 확인해봣는데, depth 이미지에서 center를 찾는 모듈과 posenet 모듈이 나눠져 잇더라구요. 그래서 먼저 보정된 center를 갖고 있다고 가정하고 실험을 진행하던데....저자가 이야기 하는 실시간이라는건 이 refining하는 부분이 포함된건지 아닌건지 모르겟어요...

 

 

이 논문 또한 코드가 공개되어있습니다.

코드 : https://github.com/mks0601/V2V-PoseNet_RELEASE

 

아쉬운 점은...lua와 torch7으로 구현이 되어있어서...전 윈도우를 주로 사용하는데...설치하려다 포기하고 linux에서 돌렸어요...ㅜㅜㅜㅜ

 

이 아쉬운 점을 메꾸기 위해 non official이지만, pytorch로 구현된 코드도 있습니다!!! 그러나.... 이 코드는 구현을 한 dataset만 해놓으셔서 다른 dataset을 위해서 약간의 코드 확장이 필요합니다. 

코드 : https://github.com/dragonbook/V2V-PoseNet-pytorch


그럼 이번 논문 리뷰도 여기서 마치겠습니다.

질문이나....오류가 있다면 댓글 언제든지 환영이에요!