이번에는 신체(body) 뿐만 아니라, 손, 얼굴을 포함한 전신에 대한 3D Pose를 예측하는 whole body pose estimation에 대해 알아보겠습니다.
Challenges
hand가 주로 어렵다 : 움직임이 많고, 작기 때문, 관절 수도 바디랑 비슷하다 (한 손당 21개 관절)
기존 방식 : Body estimator, Hand estimator, Face estimator 따로 해서 integration해서 합쳤음 (통으로 하나로 하면 ResNet에 넣었다고 치면, 8x8로 줄고, hand/face의 크기가 1px 정도라 그냥 crop해서 따로따로 하는 게 더 성능 좋음)
고려해야할 사항
3D body, hand의 연결 : 손목 rotation을 잘 추정해야 연결을 잘 할 수 있음
간단하게 3d hand, 3d body를 copy, paste 하면 해부학적으로 불가능한 자세가 나옴 - expose, frankmocap (실제로 expose나 frankmocap으로 운동 동작을 추론해봤을 때도 저런 경우가 많아서 hand까지 쓸 수가 없었습니다..)
몸과 같이 움직이기 때문에 손이 매우 빠르게 움직일 수 있음
Hand4Whole (2022) : 네트워크 아키텍처는 pose2pose 사용
3D whole-body pose estimation을 위한 정확한 3D hand 추정이 목표인 논문
3d wrist rotation : MCP 관절들(손가락들의 root 관절)의 정보가 정확한 3D wrist rotation 추정에 중요하다는 걸 발견 MCP joint들은 손목(wrist) rotation에 대한 힌트를 제공하고 있다. COCO에서 hand box 너비, 높이의 평균 : 24.4px ResNet 뒷단 가면 0.76px로 매우 작은 크기 (손 bbox 너비,높이 평균이 1px밖에 안됨 - 정보손실 심각)
3d finger rotation : 위의 ResNet 같은 경우는 손 부위에 있어 손실이 너무 크고, feature 크기도 작아서 3d finger rotation 추정에 유용한 finger 정보가 거의 없음 (손가락은 손보다 훨씬 크기가 작다)
파이프라인
High-resolution 입력이미지 (512x384) : 통상적으로 256x256인데 그것보다 크게 잡았다 (hand image를 CROP하기 위해)
hand bounding box : bodynet에서 추정, crop and resize -> 256x256 (hand의 high resolution 이미지 확보) -> ResNet 입력으로 사용
HandNet : hand이미지만 받기 때문에, hand에만 focus 할 수 있다.
finger만 추정, 3d finger rotations (손목은 가만히 있고, 손가락만 추정)
HandNet : share되는 네트워크
오른손만 학습하고, 오른손 flip해서 왼손도 잘하게 (이게 3d hand pose estimation 에서 standard한 테크닉)
face (bodynet에서 추정) : 표정, 턱 포즈 추정 (3d face parameters)
BodyNet
256x192 downsampling, ResNet에 넣어서 body pose estimation (3d joint 추출)
HandNet의 21개 feature 중 4개(MCP joint)씩 8개만 추출해서 body net joint feature와 합침
body parameter 추정(wrist도 여기서 추정)
finger는 body pose가 어떤지를 모르고, wrist는 body pose가 어떤지를 안다
3d finger rotation : body feature 안쓰고 hand feature만 사용 (일반적으로 손가락과 몸의 움직임은 독립적)
3d wrist rotation(손목추정) : body feature, MCP joint feature 모두 사용
기존 방식
hand crop해서 사용 : ExPose, FrankMocap
3d wrist 추정하는데 body feature 안쓰고, hand feature만 사용하는 데서 문제점이 생긴다.
wrist는 Body, hand를 이어주기 때문에, body 정보도 알아야 한다 (팔뚝이 어떤 자세인지 등)
3d wrist rotation 추정 시 body feature를 같이 사용함으로서, 손이 보이지 않을 때도 그럴듯한 3d wrist 추정 가능 (앞에 있는 body pose들과 더 부드럽게 연결되도록 복원 가능하기 때문에, 어깨, 팔꿈치)
3D wrist에 MCP joint 사용하는 이유
MCP JOINT들은 3d wrist rotation에 매우 필수적인 정보 제공
있으면 훨씬 정확함
모든 관절(21개) 다 쓴거보다, MCP만 쓴 게 제일 성능 좋음 : 손가락은 너무 다양하게 움직일 수 있기 때문, 손가락이 어떻게 움직이냐는 wrist에 큰 영향 X, 혼란만 줄 뿐임
video의 경우, 매 frame 마다 추정한거라 jittering 있을 수 있음
in the wild dataset 테스트 해봐도 잘됨
Code
body_position_net : body의 3d joint 좌표를 추정한다.
box_net : 이미지 feature, positionnet의 output인 body joint heatmap, body joint image가 같이 들어가서, face, left/right hand bbox 추정한다.
face, hand를 high resoultion image(inputs['img'])에서 crop하고, flipped left hand, right hand를 같이 concat해서 사용한다. ( # (2N, J_P, 3) 부분 )
추론 후에 left hand를 다시 flip back 한다
High Resolution 이미지에서 hand를 crop and resize한다 (torchvision.ops.roi_align)
shape, camera, gender는 이미지 feature를 Global average pooling해서 얻어낸다
Loss
Mocap data : 3D joint, SMPL-X parameter, SMPL-X joint
in the wild : 2D Pose, SMPL-X parameter, SMPL-X joint