# app_interface.py - Version alternative avec gr.Interface pour garantir l'API REST # Cette version utilise gr.Interface qui expose automatiquement l'API REST dans Gradio 5.x import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import gradio as gr import tensorflow as tf from tensorflow.keras.models import Model from tensorflow.keras.layers import GlobalAveragePooling2D, Dense from tensorflow.keras.applications import MobileNetV2 from ultralytics import YOLO from PIL import Image import numpy as np from sklearn.cluster import KMeans import json print("=" * 60) print("🚀 DÉMARRAGE LABASNI CLOTH DETECTION (Interface Version)") print("=" * 60) # ============================================ # CHARGEMENT DES MODÈLES # ============================================ print("\n🔄 Chargement du modĂšle YOLO...") try: yolo_model = YOLO("best.pt") print("✅ YOLO chargĂ© avec succĂšs") except Exception as e: print(f"❌ Erreur YOLO: {e}") raise print("\n🔄 Chargement du modĂšle Style/Season...") try: base_model = MobileNetV2( input_shape=(224, 224, 3), include_top=False, weights=None ) x = base_model.output x = GlobalAveragePooling2D()(x) style_output = Dense(4, activation='softmax', name='style_output')(x) season_output = Dense(4, activation='softmax', name='season_output')(x) style_model = Model( inputs=base_model.input, outputs=[style_output, season_output] ) style_model.load_weights( "style_season_model.h5", by_name=True, skip_mismatch=True ) print("✅ Style/Season model chargĂ© avec succĂšs") except Exception as e: print(f"❌ Erreur Style/Season: {e}") raise print("\n" + "=" * 60) print("✅ TOUS LES MODÈLES CHARGÉS") print("=" * 60 + "\n") # ============================================ # FONCTIONS UTILITAIRES # ============================================ def get_dominant_color(crop): """Extrait la couleur dominante via K-Means""" try: img_array = np.array(crop).reshape(-1, 3) img_array = img_array[np.any(img_array != [0, 0, 0], axis=1)] if len(img_array) == 0: return "#808080" kmeans = KMeans(n_clusters=3, random_state=0, n_init=10) kmeans.fit(img_array) dominant = kmeans.cluster_centers_[0] return '#{:02x}{:02x}{:02x}'.format( int(dominant[0]), int(dominant[1]), int(dominant[2]) ).upper() except: return "#808080" # ============================================ # FONCTION PRINCIPALE DE DÉTECTION # ============================================ def detect_cloth(image): """DĂ©tecte type, couleur, style et saison d'un vĂȘtement""" print("\n" + "="*60) print("🔍 NOUVELLE DÉTECTION") print("="*60) try: # Validation if image is None: error_result = {"error": "Aucune image fournie"} print(f"❌ {error_result['error']}") return error_result # Conversion PIL if not isinstance(image, Image.Image): image = Image.fromarray(image) img = image.convert('RGB') w, h = img.size print(f"📾 Image: {w}x{h} pixels") # YOLO Detection print("đŸ€– DĂ©tection YOLO...") results = yolo_model(img, verbose=False)[0] boxes = results.boxes if not boxes or len(boxes) == 0: error_result = {"error": "Aucun vĂȘtement dĂ©tectĂ©"} print(f"❌ {error_result['error']}") return error_result best_idx = boxes.conf.argmax() confidence = float(boxes.conf[best_idx]) print(f"✅ Confiance: {confidence:.2%}") # Extraction x1, y1, x2, y2 = map(int, boxes.xyxy[best_idx]) x1, y1 = max(0, x1), max(0, y1) x2, y2 = min(w, x2), min(h, y2) if x2 <= x1 or y2 <= y1: error_result = {"error": "BoĂźte de dĂ©tection invalide"} print(f"❌ {error_result['error']}") return error_result cropped = img.crop((x1, y1, x2, y2)) # Couleur print("🎹 Extraction couleur...") hex_color = get_dominant_color(cropped) print(f"✅ Couleur: {hex_color}") # Style & Saison print("👔 Classification...") resized = cropped.resize((224, 224)) arr = np.array(resized) / 255.0 arr = np.expand_dims(arr, axis=0) style_pred, season_pred = style_model.predict(arr, verbose=0) styles = ["casual", "formal", "sport"] seasons = ["summer", "winter", "fall", "spring"] style = styles[np.argmax(style_pred)] season = seasons[np.argmax(season_pred)] style_conf = float(np.max(style_pred)) season_conf = float(np.max(season_pred)) print(f"✅ Style: {style} ({style_conf:.2%})") print(f"✅ Saison: {season} ({season_conf:.2%})") # Type type_vetement = results.names[int(boxes.cls[best_idx])] print(f"✅ Type: {type_vetement}") # RĂ©sultat result = { "success": True, "detection": { "type": type_vetement, "color": hex_color, "style": style, "season": season }, "confidence": { "detection": f"{confidence:.2%}", "style": f"{style_conf:.2%}", "season": f"{season_conf:.2%}" } } print("="*60) print("✅ DÉTECTION RÉUSSIE") print("="*60) print(json.dumps(result, indent=2)) return result except Exception as e: error_result = {"error": f"Erreur: {str(e)}"} print(f"❌ {error_result['error']}") import traceback traceback.print_exc() return error_result # ============================================ # INTERFACE GRADIO 5.x - AVEC API GARANTIE # ============================================ # ✅ SOLUTION : Utiliser gr.Interface qui expose automatiquement l'API REST # gr.Interface garantit que l'API est accessible via /api/predict dans Gradio 5.x demo = gr.Interface( fn=detect_cloth, inputs=gr.Image( type="pil", label="📾 Photo du vĂȘtement" ), outputs=gr.JSON( label="📊 RĂ©sultat de la dĂ©tection" ), title="đŸ§„ Labasni - DĂ©tection de VĂȘtements", description=""" ## 👔 Labasni - DĂ©tection Automatique de VĂȘtements Cette API utilise l'intelligence artificielle pour analyser vos photos de vĂȘtements et dĂ©tecter : - 👕 **Type** : Haut, pantalon, robe, chaussures, etc. - 🎹 **Couleur dominante** : Code hexadĂ©cimal de la couleur principale - 👔 **Style** : Casual, Formel, Sport - đŸŒ€ïž **Saison** : ÉtĂ©, Hiver, Automne, Printemps ## 🚀 Comment utiliser 1. **Via l'interface** : Uploadez une image ci-dessous 2. **Via l'API** : Utilisez l'endpoint `/api/predict` ## 📡 Exemple d'appel API ```bash curl -X POST "https://syleto-labasni-detection.hf.space/api/predict" \\ -H "Content-Type: application/json" \\ -d '{"data": [""]}' ``` ## ⚙ ModĂšles utilisĂ©s - **YOLO** (best.pt) : DĂ©tection des vĂȘtements - **MobileNetV2** : Classification style/saison - **K-Means** : Extraction couleur dominante --- **DĂ©veloppĂ© par** : Aziz Ben Ammar & Équipe Labasni **Version** : 1.0.0 **Contact** : [Hugging Face Space](https://huggingface.co/spaces/Syleto/labasni-detection) """, theme=gr.themes.Soft(), api_name="predict" # ✅ Expose l'endpoint /api/predict ) # ============================================ # LANCEMENT # ============================================ if __name__ == "__main__": print("\n" + "="*60) print("🌐 LANCEMENT DE L'INTERFACE GRADIO") print("="*60 + "\n") # ✅ gr.Interface expose automatiquement l'API REST dans Gradio 5.x demo.launch( server_name="0.0.0.0", server_port=7860, show_error=True, share=False )