dark-metry / app.py
varundevmishra09's picture
Update app.py
7cd9f17 verified
Raw
History Blame Contribute Delete
1.74 kB
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 ----
@app.post("/analyze")
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