Spaces:
Runtime error
Runtime error
File size: 2,886 Bytes
ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 ff5f8cc 9aab4d0 | 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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | import gradio as gr
import cv2
import mediapipe as mp
import numpy as np
mp_pose = mp.solutions.pose
mp_drawing = mp.solutions.drawing_utils
def _to_uint8_rgb(img: np.ndarray) -> np.ndarray:
"""Ensure image is uint8 RGB."""
if img is None:
return None
img = np.asarray(img)
# Gradio usually provides RGB. Ensure dtype is uint8.
if img.dtype != np.uint8:
img = np.clip(img, 0, 255).astype(np.uint8)
# If someone passes grayscale, convert to RGB.
if img.ndim == 2:
img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
# If RGBA, drop alpha.
if img.ndim == 3 and img.shape[2] == 4:
img = img[:, :, :3]
return img
def _px_dist(a, b, w, h):
ax, ay = a.x * w, a.y * h
bx, by = b.x * w, b.y * h
return float(np.hypot(ax - bx, ay - by))
def analyze_body(image):
image = _to_uint8_rgb(image)
if image is None:
return None, "No image captured."
h, w = image.shape[:2]
# Create Pose per-call (safer with Gradio concurrency)
with mp_pose.Pose(
static_image_mode=True, # single-frame analysis
model_complexity=1,
min_detection_confidence=0.5
) as pose:
results = pose.process(image)
if not results.pose_landmarks:
return image, "ML Note: No body detected. Stand further back and keep your full body in frame."
annotated = image.copy()
mp_drawing.draw_landmarks(
annotated,
results.pose_landmarks,
mp_pose.POSE_CONNECTIONS
)
lm = results.pose_landmarks.landmark
ls = lm[mp_pose.PoseLandmark.LEFT_SHOULDER]
rs = lm[mp_pose.PoseLandmark.RIGHT_SHOULDER]
lh = lm[mp_pose.PoseLandmark.LEFT_HIP]
rh = lm[mp_pose.PoseLandmark.RIGHT_HIP]
shoulder_width_px = _px_dist(ls, rs, w, h)
hip_width_px = _px_dist(lh, rh, w, h)
ratio = (shoulder_width_px / hip_width_px) if hip_width_px > 1e-6 else 0.0
key_vis = [ls.visibility, rs.visibility, lh.visibility, rh.visibility]
avg_vis = float(np.mean(key_vis))
metrics = (
f"✨ ML Alignment Data:\n"
f"- Shoulder Width (px): {shoulder_width_px:.1f}\n"
f"- Hip Width (px): {hip_width_px:.1f}\n"
f"- Shoulder-to-Hip Ratio: {ratio:.2f}\n"
f"- Avg Keypoint Visibility (0-1): {avg_vis:.2f}\n"
f"Tip: Keep the same camera distance + full body in frame for consistent comparisons."
)
return annotated, metrics
with gr.Blocks() as demo:
gr.Markdown("# 📸 ML Body Progress Tracker")
with gr.Row():
input_img = gr.Image(sources=["webcam"], type="numpy", label="Webcam Feed")
output_img = gr.Image(type="numpy", label="ML Analysis (Skeleton)")
stats = gr.Textbox(label="Body Proportion Data", lines=7)
btn = gr.Button("Analyze Pose")
btn.click(fn=analyze_body, inputs=input_img, outputs=[output_img, stats])
demo.launch()
|