nemozajung commited on
Commit
c08aeab
·
verified ·
1 Parent(s): 498511d

create app.py to BMI

Browse files
Files changed (1) hide show
  1. app.py +84 -0
app.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import cv2
3
+ import numpy as np
4
+ from PIL import Image
5
+ import gradio as gr
6
+ from ultralytics import YOLO
7
+ from transformers import AutoImageProcessor, ResNetForImageClassification
8
+
9
+ # โหลด YOLOv8 โมเดลสำหรับตรวจจับบุคคล
10
+ yolo_model = YOLO("yolov8n.pt") # ใช้เวอร์ชันเล็ก (nano)
11
+
12
+ # โหลด ResNet-50 สำหรับจำแนกภาพ
13
+ resnet_model_name = "microsoft/resnet-50"
14
+ resnet_model = ResNetForImageClassification.from_pretrained(resnet_model_name)
15
+ processor = AutoImageProcessor.from_pretrained(resnet_model_name)
16
+
17
+ # ฟังก์ชันสำหรับ mapping class_id → BMI
18
+ def map_to_bmi(class_id):
19
+ if class_id < 250:
20
+ return "Underweight"
21
+ elif class_id < 500:
22
+ return "Normal"
23
+ elif class_id < 750:
24
+ return "Overweight"
25
+ else:
26
+ return "Obese"
27
+
28
+ # ฟังก์ชันสำหรับ mapping class_id → Body Type
29
+ def map_to_body_type(class_id):
30
+ if class_id % 3 == 0:
31
+ return "Ectomorph (ผอมเพรียว)"
32
+ elif class_id % 3 == 1:
33
+ return "Mesomorph (สมส่วน/ล่ำ)"
34
+ else:
35
+ return "Endomorph (ล่ำอวบ)"
36
+
37
+ # ฟังก์ชันตรวจจับและครอบตัดบุคคล
38
+ def detect_and_crop_person(image_np):
39
+ results = yolo_model(image_np)
40
+
41
+ for result in results:
42
+ for box in result.boxes:
43
+ class_id = int(box.cls)
44
+ if yolo_model.names[class_id] == 'person':
45
+ x1, y1, x2, y2 = map(int, box.xyxy[0])
46
+ cropped = image_np[y1:y2, x1:x2]
47
+ cropped_rgb = cv2.cvtColor(cropped, cv2.COLOR_BGR2RGB)
48
+ return Image.fromarray(cropped_rgb)
49
+ return None
50
+
51
+ # ฟังก์ชันหลักสำหรับ Gradio
52
+ def process_image(image):
53
+ # Convert PIL to numpy
54
+ image_np = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
55
+
56
+ # ตรวจจับและครอบตัดบุคคล
57
+ cropped = detect_and_crop_person(image_np)
58
+ if cropped is None:
59
+ return "⚠️ ไม่พบบุคคลในภาพ"
60
+
61
+ # วิเคราะห์ด้วย ResNet
62
+ inputs = processor(images=cropped, return_tensors="pt")
63
+ with torch.no_grad():
64
+ logits = resnet_model(**inputs).logits
65
+ class_id = logits.argmax(-1).item()
66
+
67
+ # แมปผลลัพธ์
68
+ bmi = map_to_bmi(class_id)
69
+ body_type = map_to_body_type(class_id)
70
+ label = resnet_model.config.id2label[class_id]
71
+
72
+ return f"📷 ResNet Label: {label}\n🧍 Body Type: {body_type}\n📏 BMI Category: {bmi}"
73
+
74
+ # สร้าง Gradio Interface
75
+ demo = gr.Interface(
76
+ fn=process_image,
77
+ inputs=gr.Image(type="pil"),
78
+ outputs="text",
79
+ title="BMI + Body Type Estimator (with YOLOv8)",
80
+ description="วิเคราะห์ BMI และลักษณะรูปร่างจากภาพถ่าย โดยใช้ YOLOv8 สำหรับตรวจจับบุคคล และ ResNet-50 สำหรับวิเคราะห์"
81
+ )
82
+
83
+ if __name__ == "__main__":
84
+ demo.launch()