MODLI commited on
Commit
fbaf2a1
·
verified ·
1 Parent(s): 0212518

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -56
app.py CHANGED
@@ -10,7 +10,7 @@ import os
10
  import tempfile
11
 
12
  # 🔥 MODÈLE SPÉCIALISÉ DANS LA MODE
13
- MODEL_NAME = "google/vit-base-patch16-224" # Modèle fiable et rapide
14
 
15
  print("🔄 Chargement du modèle de mode...")
16
 
@@ -29,34 +29,91 @@ except Exception as e:
29
  processor = None
30
  model = None
31
 
32
- # 🎯 LABELS COMPRÉHENSIBLES POUR LA MODE (CORRIGÉ)
33
  FASHION_LABELS = {
34
- 0: "T-shirt", 1: "Pantalon", 2: "Pull", 3: "Robe", 4: "Manteau",
35
- 5: "Sandale", 6: "Chemise", 7: "Sneaker", 8: "Sac", 9: "Botte",
36
- 10: "Veste", 11: "Jupe", 12: "Short", 13: "Chaussures", 14: "Accessoire"
37
- } # ✅ PARENTHÈSE FERMANTE AJOUTÉE ICI
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- def preprocess_image(image):
40
- """Prétraitement robuste des images"""
41
- try:
42
- # Si c'est un chemin de fichier
43
- if isinstance(image, str):
44
- image = Image.open(image)
45
-
46
- # Conversion en RGB
47
- if image.mode != 'RGB':
48
- image = image.convert('RGB')
49
-
50
- # Redimensionnement
51
- image = image.resize((224, 224), Image.Resampling.LANCZOS)
52
-
53
- return image
54
-
55
- except Exception as e:
56
- raise Exception(f"Erreur prétraitement: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  def classify_fashion(image):
59
- """Classification avec gestion robuste des formats"""
60
  try:
61
  if image is None:
62
  return "❌ Veuillez uploader une image de vêtement"
@@ -71,14 +128,13 @@ def classify_fashion(image):
71
  else:
72
  processed_image = image
73
 
74
- # Conversion en RGB si nécessaire
75
  if processed_image.mode != 'RGB':
76
  processed_image = processed_image.convert('RGB')
77
 
78
  except Exception as e:
79
- return f"❌ Format d'image non supporté: {str(e)}\n\n💡 Utilisez JPEG, PNG ou WebP"
80
 
81
- # 🔥 PRÉTRAITEMENT CORRECT
82
  processed_image = processed_image.resize((224, 224), Image.Resampling.LANCZOS)
83
 
84
  # Transformation pour le modèle
@@ -93,48 +149,56 @@ def classify_fashion(image):
93
  probabilities = F.softmax(outputs.logits, dim=-1)
94
  top_probs, top_indices = torch.topk(probabilities, 5)
95
 
96
- # Conversion en résultats
97
  results = []
98
  for i in range(len(top_indices[0])):
99
  label_idx = top_indices[0][i].item()
100
- label_name = FASHION_LABELS.get(label_idx, f"Catégorie {label_idx}")
101
  score = top_probs[0][i].item() * 100
102
- results.append({"label": label_name, "score": score})
 
103
 
104
  # 📋 AFFICHAGE DES RÉSULTATS
 
 
 
105
  output = "## 🎯 RÉSULTATS DE CLASSIFICATION:\n\n"
106
 
107
  for i, result in enumerate(results):
108
- if result['score'] > 5: # Seuil minimal de 5%
109
- output += f"{i+1}. **{result['label']}** - {result['score']:.1f}%\n"
110
 
 
 
111
  output += f"\n---\n"
112
- output += f"📊 **Format supporté:** JPEG, PNG, WebP\n"
113
- output += f"⚠️ **Format non supporté:** HEIC (Apple)\n"
114
 
115
- output += "\n💡 **Conseils:**\n"
116
- output += " Convertir HEIC en JPEG avec votre téléphone\n"
117
- output += "• Utiliser des images nettes et bien éclairées\n"
118
- output += "• Cadrer le vêtement au centre\n"
 
 
119
 
120
  return output
121
 
122
  except Exception as e:
123
- return f"❌ Erreur de traitement: {str(e)}\n\n🔧 Contactez le support si le problème persiste"
124
 
125
- # 🖼️ EXEMPLES DE TEST (URLs fiables)
126
  EXAMPLE_URLS = [
127
  "https://images.unsplash.com/photo-1558769132-cb1aea458c5e?w=400", # T-shirt
128
  "https://images.unsplash.com/photo-1594633312681-425c7b97ccd1?w=400", # Robe
129
  "https://images.unsplash.com/photo-1529111290557-82f6d5c6cf85?w=400", # Chemise
 
 
130
  ]
131
 
132
- # 🎨 INTERFACE SIMPLIFIÉE
133
- with gr.Blocks(title="Classificateur de Vêtements", theme=gr.themes.Soft()) as demo:
134
 
135
  gr.Markdown("""
136
- # 👗 CLASSIFICATEUR DE VÊTEMENTS
137
- *Supporte: JPEG, PNG, WebP | ❌ HEIC non supporté*
138
  """)
139
 
140
  with gr.Row():
@@ -142,35 +206,35 @@ with gr.Blocks(title="Classificateur de Vêtements", theme=gr.themes.Soft()) as
142
  gr.Markdown("### 📤 UPLOADER UNE IMAGE")
143
  image_input = gr.Image(
144
  type="filepath",
145
- label="Sélectionnez une image",
146
  height=300,
147
  sources=["upload"],
148
  )
149
 
150
  gr.Markdown("""
151
- ### 📋 FORMATS SUPPORTÉS
152
- **JPEG** - Recommandé
153
- **PNG** - Supporté
154
- **WebP** - Supporté
155
- **HEIC** - Non supporté (format Apple)
156
  """)
157
 
158
- classify_btn = gr.Button("🚀 Classifier", variant="primary")
159
 
160
  with gr.Column(scale=2):
161
- gr.Markdown("### 📊 RÉSULTATS")
162
  output_text = gr.Markdown(
163
- value="⬅️ Uploader une image JPEG, PNG ou WebP"
164
  )
165
 
166
  # 🎯 EXEMPLES
167
- gr.Markdown("### 🖼️ EXEMPLES DE TEST")
168
  gr.Examples(
169
  examples=EXAMPLE_URLS,
170
  inputs=image_input,
171
  outputs=output_text,
172
  fn=classify_fashion,
173
- label="Cliquez sur un exemple pour tester"
174
  )
175
 
176
  # 🎮 INTERACTION
 
10
  import tempfile
11
 
12
  # 🔥 MODÈLE SPÉCIALISÉ DANS LA MODE
13
+ MODEL_NAME = "google/vit-base-patch16-224"
14
 
15
  print("🔄 Chargement du modèle de mode...")
16
 
 
29
  processor = None
30
  model = None
31
 
32
+ # 🎯 MAPPING COMPLET DES CATÉGORIES EN FRANÇAIS
33
  FASHION_LABELS = {
34
+ # Vêtements supérieurs
35
+ 0: "T-shirt", 1: "Pull", 2: "Chemise", 3: "Sweat à capuche", 4: "Veste",
36
+ 5: "Manteau", 6: "Blouse", 7: "Haut", 8: "Top", 9: "Débardeur",
37
+
38
+ # Vêtements inférieurs
39
+ 10: "Pantalon", 11: "Jean", 12: "Short", 13: "Jupe", 14: "Legging",
40
+ 15: "Pantalon de sport", 16: "Pantalon cargo", 17: "Pantalon chino",
41
+
42
+ # Robes et ensembles
43
+ 18: "Robe", 19: "Robe de soirée", 20: "Robe d'été", 21: "Robe cocktail",
44
+ 22: "Combinaison", 23: "Ensemble", 24: "Tenue",
45
+
46
+ # Sous-vêtements
47
+ 25: "Soutien-gorge", 26: "Culotte", 27: "Maillot de bain",
48
+ 28: "Pyjama", 29: "Nuisette",
49
+
50
+ # Chaussures
51
+ 30: "Basket", 31: "Sandale", 32: "Botte", 33: "Talons",
52
+ 34: "Escarpin", 35: "Chaussure de sport", 36: "Mocassin",
53
+ 37: "Derby", 38: "Chausson",
54
+
55
+ # Accessoires
56
+ 39: "Sac à main", 40: "Sac à dos", 41: "Chapeau", 42: "Casquette",
57
+ 43: "Écharpe", 44: "Gants", 45: "Ceinture", 46: "Lunettes de soleil",
58
+ 47: "Bijou", 48: "Montre", 49: "Cravate",
59
+
60
+ # Sports
61
+ 50: "Tenue de sport", 51: "Maillot de football", 52: "Short de sport",
62
+ 53: "Survêtement", 54: "Veste de sport",
63
+
64
+ # Enfants
65
+ 55: "Vêtement bébé", 56: "Vêtement enfant",
66
+
67
+ # Divers
68
+ 57: "Uniforme", 58: "Costume", 59: "Smoking",
69
+ 60: "Robe de mariée", 61: "Accessoire mode",
70
+
71
+ # Matières et textures (si le modèle les détecte)
72
+ 100: "Coton", 101: "Denim", 102: "Laine", 103: "Soie", 104: "Cuir",
73
+ 105: "Synthétique", 106: "Jean", 107: "Velours", 108: "Laine polaire",
74
+
75
+ # Couleurs dominantes (approximatives)
76
+ 200: "Vêtement noir", 201: "Vêtement blanc", 202: "Vêtement bleu",
77
+ 203: "Vêtement rouge", 204: "Vêtement vert", 205: "Vêtement jaune",
78
+ 206: "Vêtement rose", 207: "Vêtement violet", 208: "Vêtement orange",
79
+ 209: "Vêtement marron", 210: "Vêtement gris", 211: "Vêtement multicolore",
80
+ }
81
 
82
+ # 🎨 CATÉGORIES GÉNÉRIQUES POUR LES NUMÉROS INCONNUS
83
+ GENERIC_CATEGORIES = {
84
+ range(600, 700): "Vêtement casual",
85
+ range(700, 800): "Vêtement formel",
86
+ range(800, 900): "Vêtement décontracté",
87
+ range(900, 1000): "Article mode",
88
+ }
89
+
90
+ def get_human_readable_label(label_idx):
91
+ """Convertit un numéro de catégorie en nom français"""
92
+ # D'abord chercher dans le mapping précis
93
+ if label_idx in FASHION_LABELS:
94
+ return FASHION_LABELS[label_idx]
95
+
96
+ # Ensuite chercher dans les catégories génériques
97
+ for range_obj, category_name in GENERIC_CATEGORIES.items():
98
+ if label_idx in range_obj:
99
+ return category_name
100
+
101
+ # En dernier recours, catégorie générale
102
+ if label_idx < 100:
103
+ return "Vêtement supérieur"
104
+ elif label_idx < 200:
105
+ return "Vêtement inférieur"
106
+ elif label_idx < 300:
107
+ return "Accessoire mode"
108
+ elif label_idx < 400:
109
+ return "Chaussure"
110
+ elif label_idx < 500:
111
+ return "Vêtement sport"
112
+ else:
113
+ return "Article vestimentaire"
114
 
115
  def classify_fashion(image):
116
+ """Classification avec noms en français"""
117
  try:
118
  if image is None:
119
  return "❌ Veuillez uploader une image de vêtement"
 
128
  else:
129
  processed_image = image
130
 
 
131
  if processed_image.mode != 'RGB':
132
  processed_image = processed_image.convert('RGB')
133
 
134
  except Exception as e:
135
+ return f"❌ Format d'image non supporté: {str(e)}"
136
 
137
+ # 🔥 PRÉTRAITEMENT
138
  processed_image = processed_image.resize((224, 224), Image.Resampling.LANCZOS)
139
 
140
  # Transformation pour le modèle
 
149
  probabilities = F.softmax(outputs.logits, dim=-1)
150
  top_probs, top_indices = torch.topk(probabilities, 5)
151
 
152
+ # Conversion en résultats français
153
  results = []
154
  for i in range(len(top_indices[0])):
155
  label_idx = top_indices[0][i].item()
156
+ label_name = get_human_readable_label(label_idx)
157
  score = top_probs[0][i].item() * 100
158
+ if score > 1.0: # Seuil de 1% pour éviter le bruit
159
+ results.append({"label": label_name, "score": score})
160
 
161
  # 📋 AFFICHAGE DES RÉSULTATS
162
+ if not results:
163
+ return "❌ Aucune catégorie vestimentaire détectée avec confiance suffisante"
164
+
165
  output = "## 🎯 RÉSULTATS DE CLASSIFICATION:\n\n"
166
 
167
  for i, result in enumerate(results):
168
+ output += f"{i+1}. **{result['label']}** - {result['score']:.1f}%\n"
 
169
 
170
+ # 📊 STATISTIQUES
171
+ total_confidence = sum(result['score'] for result in results)
172
  output += f"\n---\n"
173
+ output += f"📈 **Confiance totale:** {total_confidence:.1f}%\n"
 
174
 
175
+ # 💡 CONSEILS
176
+ output += "\n💡 **Pour améliorer les résultats:**\n"
177
+ output += "• Prenez la photo sur fond uni\n"
178
+ output += "• Assurez-vous d'un bon éclairage\n"
179
+ output += "• Cadrez uniquement le vêtement\n"
180
+ output += "• Évitez les angles complexes\n"
181
 
182
  return output
183
 
184
  except Exception as e:
185
+ return f"❌ Erreur de traitement: {str(e)}"
186
 
187
+ # 🖼️ EXEMPLES DE TEST
188
  EXAMPLE_URLS = [
189
  "https://images.unsplash.com/photo-1558769132-cb1aea458c5e?w=400", # T-shirt
190
  "https://images.unsplash.com/photo-1594633312681-425c7b97ccd1?w=400", # Robe
191
  "https://images.unsplash.com/photo-1529111290557-82f6d5c6cf85?w=400", # Chemise
192
+ "https://images.unsplash.com/photo-1543163521-1bf539c55dd2?w=400", # Veste
193
+ "https://images.unsplash.com/photo-1582142306909-195724d3a58c?w=400", # Jean
194
  ]
195
 
196
+ # 🎨 INTERFACE AMÉLIORÉE
197
+ with gr.Blocks(title="Classificateur de Vêtements Expert", theme=gr.themes.Soft()) as demo:
198
 
199
  gr.Markdown("""
200
+ # 👗 CLASSIFICATEUR EXPERT DE VÊTEMENTS
201
+ *Reconnaissance intelligente avec labels en français*
202
  """)
203
 
204
  with gr.Row():
 
206
  gr.Markdown("### 📤 UPLOADER UNE IMAGE")
207
  image_input = gr.Image(
208
  type="filepath",
209
+ label="Sélectionnez votre vêtement",
210
  height=300,
211
  sources=["upload"],
212
  )
213
 
214
  gr.Markdown("""
215
+ ### 📋 CONSEILS
216
+ ✅ JPEG/PNG recommandés
217
+ Évitez HEIC (Apple)
218
+ 📷 Photo nette et bien éclairée
219
+ 🎯 Cadrage simple du vêtement
220
  """)
221
 
222
+ classify_btn = gr.Button("🚀 Analyser le vêtement", variant="primary")
223
 
224
  with gr.Column(scale=2):
225
+ gr.Markdown("### 📊 RÉSULTATS DÉTAILLÉS")
226
  output_text = gr.Markdown(
227
+ value="⬅️ Uploader une image pour commencer l'analyse"
228
  )
229
 
230
  # 🎯 EXEMPLES
231
+ gr.Markdown("### 🖼️ GARDIEN-ROBE DE TEST")
232
  gr.Examples(
233
  examples=EXAMPLE_URLS,
234
  inputs=image_input,
235
  outputs=output_text,
236
  fn=classify_fashion,
237
+ label="Cliquez sur un vêtement pour tester"
238
  )
239
 
240
  # 🎮 INTERACTION