BMI / app.py
nemozajung's picture
create app.py to BMI
c08aeab verified
import torch
import cv2
import numpy as np
from PIL import Image
import gradio as gr
from ultralytics import YOLO
from transformers import AutoImageProcessor, ResNetForImageClassification
# โหลด YOLOv8 โมเดลสำหรับตรวจจับบุคคล
yolo_model = YOLO("yolov8n.pt") # ใช้เวอร์ชันเล็ก (nano)
# โหลด ResNet-50 สำหรับจำแนกภาพ
resnet_model_name = "microsoft/resnet-50"
resnet_model = ResNetForImageClassification.from_pretrained(resnet_model_name)
processor = AutoImageProcessor.from_pretrained(resnet_model_name)
# ฟังก์ชันสำหรับ mapping class_id → BMI
def map_to_bmi(class_id):
if class_id < 250:
return "Underweight"
elif class_id < 500:
return "Normal"
elif class_id < 750:
return "Overweight"
else:
return "Obese"
# ฟังก์ชันสำหรับ mapping class_id → Body Type
def map_to_body_type(class_id):
if class_id % 3 == 0:
return "Ectomorph (ผอมเพรียว)"
elif class_id % 3 == 1:
return "Mesomorph (สมส่วน/ล่ำ)"
else:
return "Endomorph (ล่ำอวบ)"
# ฟังก์ชันตรวจจับและครอบตัดบุคคล
def detect_and_crop_person(image_np):
results = yolo_model(image_np)
for result in results:
for box in result.boxes:
class_id = int(box.cls)
if yolo_model.names[class_id] == 'person':
x1, y1, x2, y2 = map(int, box.xyxy[0])
cropped = image_np[y1:y2, x1:x2]
cropped_rgb = cv2.cvtColor(cropped, cv2.COLOR_BGR2RGB)
return Image.fromarray(cropped_rgb)
return None
# ฟังก์ชันหลักสำหรับ Gradio
def process_image(image):
# Convert PIL to numpy
image_np = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
# ตรวจจับและครอบตัดบุคคล
cropped = detect_and_crop_person(image_np)
if cropped is None:
return "⚠️ ไม่พบบุคคลในภาพ"
# วิเคราะห์ด้วย ResNet
inputs = processor(images=cropped, return_tensors="pt")
with torch.no_grad():
logits = resnet_model(**inputs).logits
class_id = logits.argmax(-1).item()
# แมปผลลัพธ์
bmi = map_to_bmi(class_id)
body_type = map_to_body_type(class_id)
label = resnet_model.config.id2label[class_id]
return f"📷 ResNet Label: {label}\n🧍 Body Type: {body_type}\n📏 BMI Category: {bmi}"
# สร้าง Gradio Interface
demo = gr.Interface(
fn=process_image,
inputs=gr.Image(type="pil"),
outputs="text",
title="BMI + Body Type Estimator (with YOLOv8)",
description="วิเคราะห์ BMI และลักษณะรูปร่างจากภาพถ่าย โดยใช้ YOLOv8 สำหรับตรวจจับบุคคล และ ResNet-50 สำหรับวิเคราะห์"
)
if __name__ == "__main__":
demo.launch()