원문 링크 : Pose - mediapipe (google.github.io)
개요
인간 포즈 추정은 비디오에서 신체 운동의 정량화, 수화 인식 및 전신 제스처 제어와 같은 다양한 응용 프로그램에서 중요한 역할을 합니다. 예를 들어 요가, 댄스 및 피트니스 응용 프로그램의 기초를 형성할 수 있습니다. 또한 증강 현실에서 실제 세계 위에 디지털 콘텐츠 및 정보를 오버레이할 수 있습니다.
MediaPipe Pose는 ML Kit Pose Detection API를 지원하는 BlazePose 연구를 활용하여 RGB 비디오 프레임에서 전신에 대한 33개의 3D 랜드마크와 배경 분할 마스크를 추론하는 고충실도 신체 포즈 추적을 위한 ML 솔루션입니다. 현재의 최첨단 접근 방식은 추론을 위해 주로 고성능 하드웨어에 의존하는 반면, 우리의 방법(MediaPipe Pose)은 대부분의 최신 휴대 전화, 데스크톱/노트북, 파이썬 및 심지어 웹에서까지 사용이 가능합니다.
ML 파이프라인
이 솔루션은 MediaPipe Hands 및 MediaPipe Face Mesh 솔루션에서 사용되어 효과적인것으로 입증된 두 단계 탐지기 / 추적기를 사용합니다. 파이프라인은 탐지기를 사용하여 먼저 프레이 내에서 사람/포즈의 ROI(관심영역)을 찾습니다. 추적기는이후 ROI에서 잘린 프레임을 입력값으로 사용하여 ROI 내에서 포즈 랜드마크와 분할 마스크를 예측합니다. 비디오를 사용할 때는 감지기는 필요한 경우에만 호출됩니다. 즉, 첫 번째 프레임 이후 추적기가 이전 프레임에서 더 이상 포즈를 식별할 수 없는 경우에만 검출기를 호출합니다. 그 외의 경우에는 단순히 이전 프레임의 포즈 랜드마크의 ROI를 도출합니다.
이 파이프라인은 포즈 랜드마크 모듈의 포즈 랜드마크 하위 그래프를 사용하고 전용 포즈 렌더러 하위 그래프를 사용하여 렌더링하는 MediaPipe 그래프로 구현됩니다. 포즈 랜드마크의 하위 그래프는 내부적으로 포즈 감지 모듈의 포즈 감지 하위 그래프를 사용합니다.
참고: 그래프를 시각화하려면 그래프를 복사하여 MediaPipe 시각화 변환기에 붙여넣습니다. 연관된 하위 그래프를 시각화하는 방법에 대한 자세한 내용은 시각화 설명서를 참조하십시오.
포즈 추정 퀄리티
공개적으로 사용 가능한 다른 우수한 성능의 솔루션과 비교하여 우리 모델의 품질을 평가하기 위해 요가, 댄스 및 HIIT의 서로 다른 카테고리를 나타내는 3가지 다른 검증 데이터 세트를 사용합니다. 각 이미지에는 카메라에서 2~4m 떨어진 곳에 한 사람만 포함되어 있습니다. 다른 솔루션과 일관성을 유지하기 위해 COCO 토폴로지에서 17개의 키포인트에 대해서만 평가를 수행합니다.
Method | 요가(mAP) | 요가(PCK@0.2) | 춤(mAP) | 춤(PCK@0.2) | HIIT(mAP) | HIIT(PCK@0.2) |
BlazePose GHUM Heavy | 68.1 | 96.4 | 73.0 | 97.2 | 74.0 | 97.5 |
BlazePose GHUM Full | 62.6 | 95.5 | 67.4 | 96.3 | 68.0 | 95.7 |
BlazePose GHUM Lite | 45.0 | 90.2 | 53.6 | 92.5 | 53.8 | 93.5 |
AlphaPose ResNet50 | 63.4 | 96.0 | 57.8 | 95.5 | 63.4 | 96.0 |
Apple Vision | 32.8 | 82.7 | 36.4 | 91.4 | 44.5 | 88.6 |
우리는 라이브 인식을 위해 특별히 모델을 설계하여 대부분의 최신 장치에서 실시간으로 작동합니다.
Method | Latency Pixel 3 TFLite GPU |
Latency MacBook Pro (15-inch 2017) |
BlazePose GHUM Heavy | 53 ms | 38 ms |
BlazePose GHUM Full | 25 ms | 27 ms |
BlazePose GHUM Lite | 20 ms | 25 ms |
모델
포즈 감지 모델 (BlazePose 탐지기)
이 탐지기의 프록시로 MediaPipe 얼굴 탐지에 사용되는 자체 경량 BlazeFace 모델에서 영감을 받았습니다. 인체 중심, 회전 및 규모를 원으로 확실하게 설명하는 두 개의 추가 가상 키포인트를 명시적으로 예측합니다. 레오나르도 다빈치의 Vitruvian man에서 영감을 받아 엉덩이 중심점, 사람 전체를 둘러싸는 원의 반지름, 어깨와 엉덩이 중간점을 연결하는 선의 경사각을 예측합니다.
Pose Landmark Model (포즈 랜드마크 모델) (BlazePose GHUM 3D)
MediaPipe Pose의 랜드마크 모델은 33개의 포즈 랜드마크 위치를 예측합니다.
(아래 그림 참조)
선택적으로 MediaPipe 포즈는 2개의 클래스 분할(인간 또는 배경)로 표현되는 전신 분할 마스크를 예측할 수 있습니다.
Solution APIs
STATIC_IMAGE_MODE (정적_이미지_모드)
False로 설정할 경우, 이 솔루션은 비디오 스트림을 입력받습니다. 비디오 스트림의 경우 첫 프레임에서 가장 중요한 사람을 감지하려 시도하고 감지가 성공적으로 완료되면 포즈 랜드마크를 해당 사람에게 집중합니다. 그 후에는 후속 이미에서 추적을 잃기 전까지는 다른 감지를 호출하지 않고 해당 랜드 랜드마크를 추적하여 계산 및 대기 시간을 줄입니다. 만약 True로 설정할 경우 모든 입력 이미지에 사람 감지를 적용합니다. 이는 관련없는 이미지나 일괄적 정적 이미지 처리에 이상적인 모델입니다. 기본값은 False입니다.
MODEL_COMPLEXITY (모델_복잡성)
포즈 랜드마크 모델의 복잡성입니다. 0,1,2. 모델 복잡성이 높을 수록 랜드마크의 정확도와 추론 지연 시간이 늘어납니다. 기본값은 1입니다.
SMOOTH_LANDMARKS (부드러운_랜드마크)
True로 설정한다면 솔루션 필터가 지터를 줄이기 위해 다른 입력 이미지에 랜드마크를 표시합니다. 만약 '정적 이미지 모드'가 True로 설정되어 있다면 '부드러운 랜드마크'를 무시합니다. 기본값은 True입니다.
ENABLE_SEGMENTATION (분할_허용)
True로 설정합니다면 포즈 랜드마크 외에도 솔루션에서 분할 마스크를 적용합니다. 기본값은 False입니다.
SMOOTH_SEGMENTATION (부드러운_분할)
True로 설정하다면 포즈 랜드마크 외에도 솔루션에서 분할 마스크를 생성합니다. '분할 허용'이 False로 설정되어 있거나, '정적 이미지 모드'가 True일 경우 '부드러운 분할'을 무시합니다. 기본값은 True입니다.
MIN_DETECTION_CONFIDENCE (최소_탐지_신뢰값)
탐지가 성공한 것으로 간주하는 사람 탐지 모델의 최소 신뢰값은 ([0.0, 1.0])입니다. 기본값은 0.5입니다.
MIN_TRACKING_CONFIDENCE (최소_추적_신뢰값)
탐지가 성공한 것으로 간주하는 사람 탐지 모델의 최소 신뢰값은 ([0.0, 1.0])입니다. 추적에 실패하면 다음 이미지 입력에서 사람 감지가 자동으로 호출됩니다. 추적 신뢰값을 높게 설정하면 솔루션의 견고함이 증가하지만 대기시간도 증가합니다. 정적 이미지 모드가 True일 경우 무시됩니다. 기본값은 0.5입니다.
OUT PUT
POSE_LANDMARKS (포즈_랜드마크)
포즈 랜드마크의 리스트입니다. 각 랜드마크는 다음과 같이 구성됩니다.
- x와 y : 랜드마크의 좌표는 각각 이미지의 너비와 높이로 [0.0, 1.0]로 표준화됩니다.
- z : 엉덩이 중간 지점의 깊이를 원점으로 하여 랜드마크의 깊이를 나타내며, 랜드마크가 카메라에 가까울수록 값이 작아집니다. z의 크기는 x와 거의 비슷한 척도를 사용합니다.
- 가시성 : 이미지에 랜드마크가 보일 가능성(신체가 가려지지 않고 보일 경우) [0.0, 1.0] 가시성의 값입니다.
POSE_WORLD_LANDMARKS
세계 좌표에 있는 또 다른 포즈 랜드마크 리스트입니다. 각 랜드마크는 다음과 같이 구성됩니다.
- x, y, z: 엉덩이 사이의 중심에 원점이 있는 실제 3D 좌표(미터 단위)입니다.
- 가시성: 해당 pose_landmark에 정의된 것과 동일합니다.
SEGMENTATION_MASK(마스크 분할)
enable_segmentation이 True로 설정된 경우에만 작동하는 예측 출력 분할 마스크입니다. 마스크는 입력 이미지와 너비와 높이가 동일하며 [0.0, 1.0] 값을 포함합니다. 여기서 1.0과 0.0은 각각 "사람" 및 "배경" 픽셀의 높은 확실성을 나타냅니다. 자세한 사용 방법은 아래 플랫폼별 사용 예를 참조하십시오.
Python Solution API
import cv2
import mediapipe as mp
import numpy as np
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_pose = mp.solutions.pose
# 이미지 파일의 경우 이것을 사용하세요.:
IMAGE_FILES = []
BG_COLOR = (192, 192, 192) # 회색
with mp_pose.Pose(
static_image_mode=True,
model_complexity=2,
enable_segmentation=True,
min_detection_confidence=0.5) as pose:
for idx, file in enumerate(IMAGE_FILES):
image = cv2.imread(file)
image_height, image_width, _ = image.shape
# 처리 전 BGR 이미지를 RGB로 변환합니다.
results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
if not results.pose_landmarks:
continue
print(
f'Nose coordinates: ('
f'{results.pose_landmarks.landmark[mp_pose.PoseLandmark.NOSE].x * image_width}, '
f'{results.pose_landmarks.landmark[mp_pose.PoseLandmark.NOSE].y * image_height})'
)
annotated_image = image.copy()
# 이미지를 분할합니다.
# 경계 주변의 분할을 개선하려면 "image"가 있는
# "results.segmentation_mask"에 공동 양방향 필터를 적용하는 것이 좋습니다.
condition = np.stack((results.segmentation_mask,) * 3, axis=-1) > 0.1
bg_image = np.zeros(image.shape, dtype=np.uint8)
bg_image[:] = BG_COLOR
annotated_image = np.where(condition, annotated_image, bg_image)
# 이미지 위에 포즈 랜드마크를 그립니다.
mp_drawing.draw_landmarks(
annotated_image,
results.pose_landmarks,
mp_pose.POSE_CONNECTIONS,
landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style())
cv2.imwrite('/tmp/annotated_image' +
str(idx) + '.png', annotated_image)
# 포즈 월드 랜드마크를 그립니다.
mp_drawing.plot_landmarks(
results.pose_world_landmarks, mp_pose.POSE_CONNECTIONS)
# 웹캠, 영상 파일의 경우 이것을 사용하세요.:
cap = cv2.VideoCapture(0)
with mp_pose.Pose(
min_detection_confidence=0.5,
min_tracking_confidence=0.5) as pose:
while cap.isOpened():
success, image = cap.read()
if not success:
print("카메라를 찾을 수 없습니다.")
# 동영상을 불러올 경우는 'continue' 대신 'break'를 사용합니다.
continue
# 필요에 따라 성능 향상을 위해 이미지 작성을 불가능함으로 기본 설정합니다.
image.flags.writeable = False
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = pose.process(image)
# 포즈 주석을 이미지 위에 그립니다.
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
mp_drawing.draw_landmarks(
image,
results.pose_landmarks,
mp_pose.POSE_CONNECTIONS,
landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style())
# 보기 편하게 이미지를 좌우 반전합니다.
cv2.imshow('MediaPipe Pose', cv2.flip(image, 1))
if cv2.waitKey(5) & 0xFF == 27:
break
cap.release()
'Python' 카테고리의 다른 글
[백준 11047] 동전 0 해설 및 풀이 (파이썬) (0) | 2021.11.17 |
---|---|
[파이썬] pip 안될 때, 환경변수 설정하는 법 (5) | 2021.11.15 |
[파이썬] OSError: [WinError 123] 파일 이름, 디렉터리 이름 또는 볼륨 레이블 구문이 잘못되었습니다 (0) | 2021.11.12 |
[파이썬] MediaPipe 객체 인식(objectron) (0) | 2021.11.08 |
[파이썬] MediaPipe 손 인식(Hands) (0) | 2021.11.07 |
글 내용 중 잘못되거나 이해되지 않는 부분은 댓글을 달아주세요! 감사합니다! 문의: puleugo@gmail.com