varundevmishra09 commited on
Commit
7cd9f17
·
verified ·
1 Parent(s): e808b8d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -56
app.py CHANGED
@@ -2,76 +2,68 @@ from fastapi import FastAPI, UploadFile, File
2
  import cv2
3
  import numpy as np
4
  import mediapipe as mp
5
- import torch
6
- from ultralytics import YOLO
7
 
8
- app = FastAPI()
9
 
10
- # Load models
11
- yolo = YOLO("yolov8n.pt")
12
- mp_pose = mp.solutions.pose.Pose(static_image_mode=True)
13
 
14
- # ---------------- UTILITIES ---------------- #
 
 
15
 
16
- def distance(p1, p2):
17
- return np.linalg.norm(np.array(p1) - np.array(p2))
 
 
18
 
19
- def estimate_scale(bbox_height_px, camera_fov=60):
20
- # empirical scale estimation
21
- return 170 / bbox_height_px
22
 
23
- # ---------------- CORE LOGIC ---------------- #
24
 
25
- @app.post("/analyze-image")
26
- async def analyze_image(file: UploadFile = File(...)):
27
- image_bytes = await file.read()
28
- img_np = np.frombuffer(image_bytes, np.uint8)
29
- image = cv2.imdecode(img_np, cv2.IMREAD_COLOR)
30
 
31
- # 1. Person detection
32
- results = yolo(image, conf=0.4)
33
- if len(results[0].boxes) == 0:
34
- return {"error": "No human detected"}
 
 
 
35
 
36
- box = results[0].boxes.xyxy[0].cpu().numpy()
37
- x1, y1, x2, y2 = map(int, box)
38
- person = image[y1:y2, x1:x2]
39
 
40
- # 2. Pose estimation
41
- rgb = cv2.cvtColor(person, cv2.COLOR_BGR2RGB)
42
- pose_result = mp_pose.process(rgb)
43
- if not pose_result.pose_landmarks:
44
- return {"error": "Pose not detected"}
45
 
46
- h, w, _ = person.shape
47
- lm = pose_result.pose_landmarks.landmark
48
 
49
- left_shoulder = (lm[11].x * w, lm[11].y * h)
50
- right_shoulder = (lm[12].x * w, lm[12].y * h)
51
- left_hip = (lm[23].x * w, lm[23].y * h)
52
- right_hip = (lm[24].x * w, lm[24].y * h)
53
 
54
- shoulder_px = distance(left_shoulder, right_shoulder)
55
- hip_px = distance(left_hip, right_hip)
56
 
57
- # 3. Scale estimation
58
- bbox_height = y2 - y1
59
- scale = estimate_scale(bbox_height)
 
 
 
60
 
61
- # 4. Final metrics
62
- height_cm = bbox_height * scale
63
- shoulder_cm = shoulder_px * scale
 
 
64
 
65
- # Learned-like regression (approx industrial)
66
- weight_kg = (
67
- 0.45 * height_cm +
68
- 1.2 * shoulder_cm +
69
- 0.8 * hip_px * scale
70
- ) / 10
71
 
72
- return {
73
- "height_cm": round(height_cm, 2),
74
- "shoulder_cm": round(shoulder_cm, 2),
75
- "weight_kg": round(weight_kg, 2),
76
- "confidence": 0.9
77
- }
 
2
  import cv2
3
  import numpy as np
4
  import mediapipe as mp
 
 
5
 
6
+ app = FastAPI(title="Human Anthropometry API")
7
 
8
+ mp_pose = mp.solutions.pose
9
+ pose = mp_pose.Pose(static_image_mode=False)
 
10
 
11
+ # ---- Utility ----
12
+ def dist(a, b):
13
+ return np.linalg.norm(a - b)
14
 
15
+ def analyze_frame(image):
16
+ h, w, _ = image.shape
17
+ rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
18
+ res = pose.process(rgb)
19
 
20
+ if not res.pose_landmarks:
21
+ return None
 
22
 
23
+ lm = res.pose_landmarks.landmark
24
 
25
+ def p(i):
26
+ return np.array([lm[i].x * w, lm[i].y * h])
 
 
 
27
 
28
+ head = p(0)
29
+ l_sh = p(11)
30
+ r_sh = p(12)
31
+ l_hip = p(23)
32
+ r_hip = p(24)
33
+ l_heel = p(29)
34
+ r_heel = p(30)
35
 
36
+ shoulder_px = dist(l_sh, r_sh)
37
+ torso_px = dist((l_sh + r_sh)/2, (l_hip + r_hip)/2)
38
+ height_px = dist(head, (l_heel + r_heel)/2)
39
 
40
+ # ---- INDUSTRIAL NORMALIZATION ----
41
+ # Average adult shoulder width ≈ 0.23 × height
42
+ height_cm = (shoulder_px / height_px) * (1 / 0.23) * 100
 
 
43
 
44
+ shoulder_cm = height_cm * 0.23
45
+ torso_ratio = torso_px / height_px
46
 
47
+ # Weight estimation via body volume proxy (not BMI)
48
+ weight_kg = round((height_cm * shoulder_cm * torso_ratio) / 1000, 1)
 
 
49
 
50
+ confidence = round(min(0.95, 0.6 + torso_ratio), 2)
 
51
 
52
+ return {
53
+ "height_cm": round(height_cm, 1),
54
+ "shoulder_cm": round(shoulder_cm, 1),
55
+ "weight_kg": weight_kg,
56
+ "confidence": confidence
57
+ }
58
 
59
+ # ---- API ----
60
+ @app.post("/analyze")
61
+ async def analyze(file: UploadFile = File(...)):
62
+ data = await file.read()
63
+ img = cv2.imdecode(np.frombuffer(data, np.uint8), cv2.IMREAD_COLOR)
64
 
65
+ result = analyze_frame(img)
66
+ if not result:
67
+ return {"error": "Human not detected"}
 
 
 
68
 
69
+ return result