Spaces:
Sleeping
Sleeping
| 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() |