์ด๋ฒ ํฌ์คํ ์์๋ MediaPipe Holistic์ ํ์ฉํ์ฌ ๋ชจ์ ์ธ์์ ํ๊ณ , ์ด๋ฏธ์ง์์ ์ถ์ถํ ๋๋๋งํฌ ๋ฐ์ดํฐ๋ฅผ JSON ํ์ผ๋ก ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ ๋จ๊ณ๋ณ๋ก ์ค๋ช ํ๊ฒ ์ต๋๋ค.
<๋ชฉ์ฐจ>
1. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ํฌํธ ๋ฐ MediaPipe ์ด๊ธฐํ
2. ์ด๋ฏธ์ง ํ์ผ ๋ชฉ๋ก ๋ฐ ๋๋๋งํฌ ๋ฐ์ดํฐ ๋ฆฌ์คํธ ์ค์
3. ๋๋๋งํฌ ๋ฐ์ดํฐ ์ถ์ถ ํจ์ ์ ์
4. MediaPipe Holistic์ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง ์ฒ๋ฆฌ
5. ๊ฐ์ง๋ ๋๋๋งํฌ ๋ฐ์ดํฐ ์ถ์ถ ๋ฐ ์ ์ฅ
6. ์ด๋ฏธ์ง์ ๋๋๋งํฌ ์ฃผ์ ์ถ๊ฐ
7. ๋๋๋งํฌ ๋ฐ์ดํฐ๋ฅผ JSON ํ์ผ๋ก ์ ์ฅ
8. ๊ฒฐ๊ณผ
9. ์ฐธ๊ณ
1. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ํฌํธ ๋ฐ MediaPipe ์ด๊ธฐํ
๋จผ์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ํฌํธํ๊ณ , MediaPipe Holistic๊ณผ ๊ทธ๋ฆฌ๊ธฐ ์ ํธ๋ฆฌํฐ๋ฅผ ์ด๊ธฐํํฉ๋๋ค.
import cv2
import mediapipe as mp
import json
import matplotlib.pyplot as plt
# MediaPipe Holistic ๋ฐ ๊ทธ๋ฆฌ๊ธฐ ์ ํธ๋ฆฌํฐ ์ด๊ธฐํ
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_holistic = mp.solutions.holistic
2. ์ด๋ฏธ์ง ํ์ผ ๋ชฉ๋ก ๋ฐ ๋๋๋งํฌ ๋ฐ์ดํฐ ๋ฆฌ์คํธ ์ค์
์ฒ๋ฆฌํ ์ด๋ฏธ์ง ํ์ผ ๋ชฉ๋ก์ ์ค์ ํ๊ณ , ๋๋๋งํฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋ฆฌ์คํธ๋ฅผ ์ค๋นํฉ๋๋ค.
# ์ฒ๋ฆฌํ ์ด๋ฏธ์ง ํ์ผ ๋ชฉ๋ก
IMAGE_FILES = ["../singlePerson_image/yoo/balance.jpeg"]
BG_COLOR = (192, 192, 192)
# ๋๋๋งํฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋ฆฌ์คํธ
landmarks_data = []
3. ๋๋๋งํฌ ๋ฐ์ดํฐ ์ถ์ถ ํจ์ ์ ์
๋๋๋งํฌ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ์ฌ ๋ฆฌ์คํธ๋ก ๋ฐํํ๋ ํจ์๋ฅผ ์ ์ํฉ๋๋ค. ์ด ํจ์๋ ๊ฐ ๋๋๋งํฌ์ ์ด๋ฆ๊ณผ ์ขํ(x, y, z)๋ฅผ ํฌํจํฉ๋๋ค.
def extract_landmark_data(landmarks, landmark_enum=None):
if landmark_enum is not None:
return [{'name': landmark_enum(lm_idx).name, 'x': lm.x, 'y': lm.y, 'z': lm.z, 'visibility': lm.visibility if hasattr(lm, 'visibility') else None}
for lm_idx, lm in enumerate(landmarks.landmark)]
else:
return [{'index': lm_idx, 'x': lm.x, 'y': lm.y, 'z': lm.z, 'visibility': lm.visibility if hasattr(lm, 'visibility') else None}
for lm_idx, lm in enumerate(landmarks.landmark)]
4. MediaPipe Holistic์ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง ์ฒ๋ฆฌ
์ด๋ฏธ์ง๋ฅผ ์ฝ๊ณ , MediaPipe Holistic์ ์ฌ์ฉํ์ฌ ํฌ์ฆ, ์ผ๊ตด, ์์ ๋๋๋งํฌ๋ฅผ ๊ฐ์งํฉ๋๋ค.
with mp_holistic.Holistic(
static_image_mode=True,
model_complexity=2,
enable_segmentation=True,
refine_face_landmarks=True) as holistic:
for idx, file in enumerate(IMAGE_FILES):
# ์ด๋ฏธ์ง ์ฝ๊ธฐ
image = cv2.imread(file)
image_height, image_width, _ = image.shape
results = holistic.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
5. ๊ฐ์ง๋ ๋๋๋งํฌ ๋ฐ์ดํฐ ์ถ์ถ ๋ฐ ์ ์ฅ
๊ฐ์ง๋ ๋๋๋งํฌ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ์ฌ ๋ฆฌ์คํธ์ ์ ์ฅํฉ๋๋ค
landmarks = {}
if results.pose_landmarks:
landmarks['pose_landmarks'] = extract_landmark_data(results.pose_landmarks, mp_holistic.PoseLandmark)
if results.face_landmarks:
landmarks['face_landmarks'] = extract_landmark_data(results.face_landmarks)
if results.left_hand_landmarks:
landmarks['left_hand_landmarks'] = extract_landmark_data(results.left_hand_landmarks, mp_holistic.HandLandmark)
if results.right_hand_landmarks:
landmarks['right_hand_landmarks'] = extract_landmark_data(results.right_hand_landmarks, mp_holistic.HandLandmark)
landmarks_data.append({
'file': file,
'landmarks': landmarks
})
6. ์ด๋ฏธ์ง์ ๋๋๋งํฌ ์ฃผ์ ์ถ๊ฐ
๊ฐ์ง๋ ๋๋๋งํฌ๋ฅผ ์ด๋ฏธ์ง์ ๊ทธ๋ ค์ ์ฃผ์์ ์ถ๊ฐํฉ๋๋ค.
# ์ด๋ฏธ์ง์ ๋๋๋งํฌ ๊ทธ๋ฆฌ๊ธฐ
annotated_image = image.copy()
mp_drawing.draw_landmarks(annotated_image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
mp_drawing.draw_landmarks(annotated_image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
if results.face_landmarks:
for landmark in results.face_landmarks.landmark:
x = int(landmark.x * image_width)
y = int(landmark.y * image_height)
cv2.circle(annotated_image, (x, y), 1, (0, 255, 0), -1)
mp_drawing.draw_landmarks(
annotated_image,
results.pose_landmarks,
mp_holistic.POSE_CONNECTIONS,
landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style()
)
# ์ฃผ์ ์ฒ๋ฆฌ๋ ์ด๋ฏธ์ง ํ์
fig = plt.figure(figsize=[10, 10])
plt.title("Output")
plt.axis('off')
plt.imshow(annotated_image[:, :, ::-1])
plt.show()
7. ๊ฒฐ๊ณผ
8. ์ฐธ๊ณ
https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/holistic.md
์ด ๋จ๊ณ๋ฅผ ํตํด MediaPipe Holistic์ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง์์ ๋๋๋งํฌ๋ฅผ ์ถ์ถํ๊ณ , ์ด๋ฅผ ์๊ฐํํ๋ฉฐ, ๋ฐ์ดํฐ๋ฅผ JSON ํ์ผ๋ก ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ต๋๋ค. ์ด ๋ฐ์ดํฐ๋ ๋ค์ํ ๋ชจ์ ๋ถ์ ๋ฐ ์ ์ค์ฒ ์ธ์ ์์ฉ ํ๋ก๊ทธ๋จ์ ํ์ฉ๋ ์ ์์ต๋๋ค.