Spaces:
Runtime error
Runtime error
| from fastapi import FastAPI, UploadFile, File | |
| import cv2 | |
| import numpy as np | |
| import mediapipe as mp | |
| app = FastAPI(title="Human Anthropometry API") | |
| mp_pose = mp.solutions.pose | |
| pose = mp_pose.Pose(static_image_mode=False) | |
| # ---- Utility ---- | |
| def dist(a, b): | |
| return np.linalg.norm(a - b) | |
| def analyze_frame(image): | |
| h, w, _ = image.shape | |
| rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) | |
| res = pose.process(rgb) | |
| if not res.pose_landmarks: | |
| return None | |
| lm = res.pose_landmarks.landmark | |
| def p(i): | |
| return np.array([lm[i].x * w, lm[i].y * h]) | |
| head = p(0) | |
| l_sh = p(11) | |
| r_sh = p(12) | |
| l_hip = p(23) | |
| r_hip = p(24) | |
| l_heel = p(29) | |
| r_heel = p(30) | |
| shoulder_px = dist(l_sh, r_sh) | |
| torso_px = dist((l_sh + r_sh)/2, (l_hip + r_hip)/2) | |
| height_px = dist(head, (l_heel + r_heel)/2) | |
| # ---- INDUSTRIAL NORMALIZATION ---- | |
| # Average adult shoulder width ≈ 0.23 × height | |
| height_cm = (shoulder_px / height_px) * (1 / 0.23) * 100 | |
| shoulder_cm = height_cm * 0.23 | |
| torso_ratio = torso_px / height_px | |
| # Weight estimation via body volume proxy (not BMI) | |
| weight_kg = round((height_cm * shoulder_cm * torso_ratio) / 1000, 1) | |
| confidence = round(min(0.95, 0.6 + torso_ratio), 2) | |
| return { | |
| "height_cm": round(height_cm, 1), | |
| "shoulder_cm": round(shoulder_cm, 1), | |
| "weight_kg": weight_kg, | |
| "confidence": confidence | |
| } | |
| # ---- API ---- | |
| async def analyze(file: UploadFile = File(...)): | |
| data = await file.read() | |
| img = cv2.imdecode(np.frombuffer(data, np.uint8), cv2.IMREAD_COLOR) | |
| result = analyze_frame(img) | |
| if not result: | |
| return {"error": "Human not detected"} | |
| return result | |