Spaces:
Sleeping
Sleeping
File size: 2,595 Bytes
f7c47ba |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
import cv2
import numpy as np
import mediapipe as mp
import gradio as gr
# Initialize Mediapipe Pose
mp_pose = mp.solutions.pose
mp_drawing = mp.solutions.drawing_utils
pose = mp_pose.Pose(static_image_mode=True, min_detection_confidence=0.5)
def calculate_angle(a, b, c):
"""Calculate angle between three points (for body extension)."""
a = np.array(a) # Point A
b = np.array(b) # Joint (Point B)
c = np.array(c) # Point C
ba = a - b
bc = c - b
cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
angle = np.arccos(cosine_angle)
return np.degrees(angle)
def detect_pose(image):
"""Detect pose in an image and return annotated image + example angle."""
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = pose.process(image_rgb)
annotated = image.copy()
angle_text = "No person detected"
if results.pose_landmarks:
# Draw pose landmarks
mp_drawing.draw_landmarks(
annotated,
results.pose_landmarks,
mp_pose.POSE_CONNECTIONS,
mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2),
mp_drawing.DrawingSpec(color=(0, 0, 255), thickness=2)
)
# Example: Calculate elbow angle (shoulder-elbow-wrist)
h, w, _ = image.shape
landmarks = results.pose_landmarks.landmark
shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x * w,
landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y * h]
elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x * w,
landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y * h]
wrist = [landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].x * w,
landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].y * h]
angle = calculate_angle(shoulder, elbow, wrist)
angle_text = f"Left Elbow Angle: {int(angle)}°"
cv2.putText(annotated, angle_text, (20, 40),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 2)
return annotated[:, :, ::-1], angle_text # Convert BGR → RGB for Gradio
# Gradio Interface
demo = gr.Interface(
fn=detect_pose,
inputs=gr.Image(type="numpy", label="Upload Image"),
outputs=[gr.Image(type="numpy", label="Pose Estimation"), gr.Textbox(label="Body Extension Angle")],
title="Human Pose Estimation with MediaPipe",
description="Upload an image with a person doing exercise. The app will detect body pose and calculate joint angles."
)
if __name__ == "__main__":
demo.launch()
|