mediapipe를 사용해 모션캡쳐하기
-
mediapipe는 구글에서 만든 모션 캡쳐 라이브러리다.
- 기존의 모션 캡쳐 라이브러리가 2D에서 2D를 인식하는 한계가 있었다면, 이 라이브러리는 2D이미지를 가지고 3D를 인식하는 것이 목표이다.
- python, android, ios, C++ 버전이 있으며, 온 디바이스에서 바로 인식하는것을 목표로 개발중이다.
- Pose, Hand, Face, Object 트래킹등 모션 캡쳐에 필요한 대부분의 기능이 포함되어 있고, 여러가지를 동시에 사용할 수도 있다.
- 현재는 ML이 적용된 새로운 버전이 나오고 있다.
- 일부 기능에만 ML이 적용된 버전이 있는데, 모든 기능에 대해서 나온다면 훨씬 좋은 성능을 낼 것으로 기대된다.
- 기존의 모션 캡쳐 라이브러리가 2D에서 2D를 인식하는 한계가 있었다면, 이 라이브러리는 2D이미지를 가지고 3D를 인식하는 것이 목표이다.
-
필요 라이브러리
numpy opencv-python mediapipe
-
사용방법
-
Legacy와 새로운 버전에 따라 사용방법이 조금 다르다
-
legacy 버전 사용 방법 (pose)
import cv2 import mediapipe as mp from mediapipe.python.solutions import drawing_utils as mp_drawing from mediapipe.python.solutions import pose as mp_pose image = mp.Image.create_from_file("image.jpg") with mp_pose.Pose() as pose_tracker: result = pose_tracker.process(image=image) overlay_image = image.copy() pl = result.pose_landmarks mp_drawing.draw_landmarks( image=overlay_image, landmark_list=pl, connections=mp_pose.POSE_CONNECTIONS) cv2.imwrite(path, cv2.cvtColor(overlay_image, cv2.COLOR_RGB2BGR))
-
신버전 사용 방법
- 신 버전은 model을 다운받아야 하며, 아직까지 Hand, Object Detection등 제한된 기능만 가능하다. 출처
# STEP 1: Import the necessary modules. import mediapipe as mp from mediapipe.tasks import python from mediapipe.tasks.python import vision # STEP 2: Create an ImageClassifier object. base_options = python.BaseOptions(model_asset_path='hand_landmarker.task') options = vision.HandLandmarkerOptions(base_options=base_options, num_hands=2) detector = vision.HandLandmarker.create_from_options(options) # STEP 3: Load the input image. image = mp.Image.create_from_file("image.jpg") # STEP 4: Detect hand landmarks from the input image. detection_result = detector.detect(image) # STEP 5: Process the classification result. In this case, visualize it. annotated_image = draw_landmarks_on_image(image.numpy_view(), detection_result) cv2_imshow(cv2.cvtColor(annotated_image, cv2.COLOR_RGB2BGR))
-
동영상의 경우, 프레임 단위로 이미지를 분리한 뒤 모든 이미지에 대해 동일하게 사용하면 된다.
-
결과물의 landmark를 사용해서 모션캡쳐 데이터를 가져올 수 있다.
result = pose_tracker.process(image=image) # Legacy version result = detector.detect(image) # New version print(result.hand_landmarks) > [[NormalizedLandmark(x=0.3925739526748657, y=0.7065041661262512, z=-3.275009419212438e-07, visibility=0.0, presence=0.0), NormalizedLandmark(x=0.3429622948169708, y=0.7502768039703369, z=-0.01981717348098755, visibility=0.0, presence=0.0), ...], [NormalizedLandmark(x=0.3925739526748657, y=0.7065041661262512, z=-3.275009419212438e-07, visibility=0.0, presence=0.0), NormalizedLandmark(x=0.3429622948169708, y=0.7502768039703369, z=-0.01981717348098755, visibility=0.0, presence=0.0), ...]] print(result.handness) > [[Category(index=1, score=0.9360456466674805, display_name='Right', category_name='Right')], [Category(index=0, score=0.9622023105621338, display_name='Left', category_name='Left')]]
- Hand Detection의 경우 아래와 같이 landmark가 배열되어 있다.
- PoseDetection의 경우 아래와 같다.
- Hand Detection의 경우 아래와 같이 landmark가 배열되어 있다.
-
-
landmark만 가져와서 간단히 처리하고 Unity3D에서 돌리는 모습
- {{[[video]]: https://youtu.be/1ra58BYm72s}}
-
아직 Z축 검사가 잘 안되는것이 아쉽다.
- 실제로는 팔을 앞뒤로 열심히 흔들었지만, 캡쳐된 모습은 좌우로만 흔드는 모습이다.
- {{[[video]]: https://youtu.be/Q3NlGVuWVuc}}
- 지금은 소프트웨어적으로 처리하는 듯 하다.
- Human Pose Estimation Using MediaPipe Pose and Optimization Method Based on a Humanoid Model 동아대학교에서 소프트웨어적으로 z 축을 계산한 논문
- 신 버전에서는 이를 개선하기위해 작업중이라고… 문서
- 실제로는 팔을 앞뒤로 열심히 흔들었지만, 캡쳐된 모습은 좌우로만 흔드는 모습이다.
-
카메라를 두 대 설치하고, 각각 정면, 측면을 촬영해서 하면 어떨까? 싶지만…
- 테스트삼아 측면으로 찍었을 때 왼팔, 오른팔의 구분이 잘 안되는 문제가 있었다.
- 그리고 두 개의 카메라의 싱크를 맞추는 것도, 꽤 난이도가 있을것으로 생각된다.