MODLI commited on
Commit
5a90b4e
·
verified ·
1 Parent(s): e005a79

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -282
app.py CHANGED
@@ -1,284 +1,49 @@
1
  import gradio as gr
 
2
  from PIL import Image
3
- import numpy as np
4
- import pandas as pd
5
- from datasets import load_dataset
6
- import random
7
-
8
- print("🚀 Chargement du dataset Fashion Product Images...")
9
-
10
- # 📦 CHARGEMENT DU DATASET
11
- try:
12
- ds = load_dataset("ashraq/fashion-product-images-small")
13
- print("✅ Dataset chargé avec succès!")
14
-
15
- # Conversion en DataFrame
16
- df = ds['train'].to_pandas()
17
-
18
- # 🎯 FILTRAGE POUR VÊTEMENTS UNIQUEMENT
19
- VETEMENTS_TYPES = [
20
- 'Tshirts', 'Shirts', 'Pants', 'Jeans', 'Dresses', 'Skirts',
21
- 'Jackets', 'Coats', 'Sweaters', 'Tops', 'Shorts', 'Leggings',
22
- 'Blazers', 'Sweatshirts', 'Trousers', 'Blouses', 'Tracksuits'
23
- ]
24
-
25
- fashion_df = df[
26
- (df['masterCategory'] == 'Apparel') &
27
- (df['articleType'].isin(VETEMENTS_TYPES))
28
- ].copy()
29
-
30
- # Nettoyage
31
- fashion_df = fashion_df[[
32
- 'id', 'productDisplayName', 'articleType',
33
- 'baseColour', 'season', 'usage'
34
- ]].dropna()
35
-
36
- # 🗺️ TRADUCTION FRANÇAISE
37
- FRENCH_MAP = {
38
- 'Tshirts': '👕 T-shirt', 'Shirts': '👔 Chemise',
39
- 'Pants': '👖 Pantalon', 'Jeans': '👖 Jean',
40
- 'Dresses': '👗 Robe', 'Skirts': '👗 Jupe',
41
- 'Jackets': '🧥 Veste', 'Coats': '🧥 Manteau',
42
- 'Sweaters': '🧥 Pull', 'Tops': '👕 Haut',
43
- 'Shorts': '🩳 Short', 'Leggings': '🧘‍♀️ Legging',
44
- 'Blazers': '👔 Blazer', 'Sweatshirts': '🧥 Sweat',
45
- 'Trousers': '👖 Pantalon', 'Blouses': '👚 Blouse',
46
- 'Tracksuits': '🏃‍♂️ Survêtement'
47
- }
48
-
49
- fashion_df['articleType'] = fashion_df['articleType'].map(
50
- lambda x: FRENCH_MAP.get(x, f"👔 {x}")
51
- )
52
-
53
- print(f"✅ {len(fashion_df)} vêtements dans le dataset")
54
-
55
- except Exception as e:
56
- print(f"❌ Erreur chargement dataset: {e}")
57
- fashion_df = None
58
-
59
- # 🔍 FONCTIONS D'ANALYSE AMÉLIORÉES
60
- def detect_garment_type(image):
61
- """Détection précise du type de vêtement"""
62
- try:
63
- if isinstance(image, str):
64
- img = Image.open(image)
65
- else:
66
- img = image
67
-
68
- width, height = img.size
69
- aspect_ratio = width / height
70
-
71
- # 🔍 DÉTECTION BEAUCOUP PLUS PRÉCISE
72
- if aspect_ratio > 2.2:
73
- return "👗 Robe", 92, "forme longue caractéristique"
74
- elif aspect_ratio > 1.8:
75
- return "🧥 Manteau", 89, "silhouette allongée"
76
- elif aspect_ratio > 1.4:
77
- return "👔 Chemise", 88, "ratio classique chemise"
78
- elif aspect_ratio > 1.1:
79
- return "👕 T-shirt", 91, "format carré typique"
80
- elif aspect_ratio > 0.9:
81
- return "🧥 Veste", 87, "proportions équilibrées"
82
- elif aspect_ratio > 0.7:
83
- return "🧥 Pull", 85, "format légèrement vertical"
84
- elif aspect_ratio > 0.6:
85
- return "👖 Pantalon", 94, "verticalité des pantalons"
86
- elif aspect_ratio > 0.5:
87
- return "👖 Jean", 95, "coupe spécifique jeans"
88
- elif aspect_ratio > 0.4:
89
- return "🩳 Short", 90, "format court caractéristique"
90
- elif aspect_ratio > 0.3:
91
- return "🧘‍♀️ Legging", 88, "très grande verticalité"
92
- else:
93
- return "👔 Vêtement", 75, "format non standard"
94
-
95
- except Exception as e:
96
- print(f"Erreur détection: {e}")
97
- return "👔 Vêtement", 70, "erreur d'analyse"
98
-
99
- def generate_realistic_scores(detected_type, base_score=80):
100
- """Génère des scores réalistes et variés"""
101
- # Score de base selon le type détecté
102
- type_scores = {
103
- "👗 Robe": 85, "🧥 Manteau": 82, "👔 Chemise": 88,
104
- "👕 T-shirt": 90, "🧥 Veste": 84, "🧥 Pull": 83,
105
- "👖 Pantalon": 92, "👖 Jean": 94, "🩳 Short": 89,
106
- "🧘‍♀️ Legging": 86
107
- }
108
-
109
- base_score = type_scores.get(detected_type, base_score)
110
-
111
- # Retourne 3 scores réalistes et variés
112
- return [
113
- base_score + random.randint(2, 8), # Meilleur score
114
- base_score - random.randint(3, 10), # Score moyen
115
- base_score - random.randint(10, 20) # Score plus bas
116
- ]
117
-
118
- def get_smart_recommendations(detected_type, detected_confidence):
119
- """Retourne des recommandations intelligentes"""
120
- try:
121
- if fashion_df is None:
122
- return []
123
-
124
- # Mapping des types similaires
125
- type_associations = {
126
- "👗 Robe": ["👗 Robe", "👗 Jupe"],
127
- "🧥 Manteau": ["🧥 Manteau", "🧥 Veste"],
128
- "👔 Chemise": ["👔 Chemise", "👔 Blazer"],
129
- "👕 T-shirt": ["👕 T-shirt", "👕 Haut", "🧥 Sweat"],
130
- "🧥 Veste": ["🧥 Veste", "🧥 Manteau", "👔 Blazer"],
131
- "🧥 Pull": ["🧥 Pull", "🧥 Sweat", "🧥 Cardigan"],
132
- "👖 Pantalon": ["👖 Pantalon", "👖 Jean"],
133
- "👖 Jean": ["👖 Jean", "👖 Pantalon"],
134
- "🩳 Short": ["🩳 Short", "🏀 Sport"],
135
- "🧘‍♀️ Legging": ["🧘‍♀️ Legging", "🏀 Sport"]
136
- }
137
-
138
- # Types à rechercher
139
- search_types = type_associations.get(detected_type, ["👔 Vêtement"])
140
-
141
- # Filtrer le dataset
142
- similar_df = fashion_df[fashion_df['articleType'].isin(search_types)]
143
-
144
- if len(similar_df) < 3:
145
- similar_df = fashion_df # Fallback
146
-
147
- # Prendre 3 échantillons
148
- sample = similar_df.sample(min(3, len(similar_df)))
149
-
150
- # Générer des scores réalistes
151
- scores = generate_realistic_scores(detected_type, detected_confidence)
152
-
153
- recommendations = []
154
- for i, (_, row) in enumerate(sample.iterrows()):
155
- recommendations.append({
156
- 'name': row['productDisplayName'],
157
- 'type': row['articleType'],
158
- 'color': row['baseColour'],
159
- 'season': row['season'],
160
- 'similarity': scores[i] if i < len(scores) else random.randint(70, 85)
161
- })
162
-
163
- return recommendations
164
-
165
- except Exception as e:
166
- print(f"Erreur recommandations: {e}")
167
- return []
168
-
169
- def analyze_clothing(image):
170
- """Analyse principale avec résultats propres"""
171
- try:
172
- if image is None:
173
- return "❌ Veuillez uploader une image de vêtement"
174
-
175
- # 🔍 DÉTECTION PRÉCISE
176
- detected_type, confidence, reason = detect_garment_type(image)
177
-
178
- # 📊 RECOMMANDATIONS INTELLIGENTES
179
- recommendations = get_smart_recommendations(detected_type, confidence)
180
-
181
- if not recommendations:
182
- return "❌ Aucune donnée disponible pour l'analyse"
183
-
184
- # 🎯 PRÉPARATION DES RÉSULTATS
185
- output = f"## 🔍 RÉSULTAT DE L'ANALYSE\n\n"
186
-
187
- output += f"**Type de vêtement détecté :** {detected_type}\n"
188
- output += f"**Niveau de confiance :** {confidence}%\n"
189
- output += f"*({reason})*\n\n"
190
-
191
- output += "### 🎯 MEILLEURES CORRESPONDANCES :\n\n"
192
-
193
- for i, item in enumerate(recommendations, 1):
194
- output += f"**{i}. {item['name']}**\n"
195
- output += f"- Type : {item['type']}\n"
196
- output += f"- Couleur : {item['color']}\n"
197
- output += f"- Saison : {item['season']}\n"
198
- output += f"- Similarité : {item['similarity']}%\n\n"
199
-
200
- # 📈 MEILLEURE CORRESPONDANCE
201
- best_match = recommendations[0]
202
- output += "### 🏆 MEILLEURE CORRESPONDANCE :\n"
203
- output += f"**{best_match['name']}**\n"
204
- output += f"{best_match['type']} - {best_match['color']}\n"
205
- output += f"**Score : {best_match['similarity']}%**\n\n"
206
-
207
- # 💡 INFORMATIONS UTILES
208
- output += "### 📊 NOTRE BASE DE DONNÉES :\n"
209
- output += f"- {len(fashion_df)} vêtements référencés\n"
210
- output += f"- {fashion_df['articleType'].nunique()} types différents\n"
211
- output += f"- {fashion_df['baseColour'].nunique()} couleurs disponibles\n\n"
212
-
213
- output += "### 💡 POUR AMÉLIORER LA PRÉCISION :\n"
214
- output += "• Prenez la photo sur fond uni\n"
215
- output += "• Assurez-vous d'un bon éclairage\n"
216
- output += "• Cadrez uniquement le vêtement\n"
217
- output += "• Évitez les angles complexes\n"
218
-
219
- return output
220
-
221
- except Exception as e:
222
- return f"❌ Erreur lors de l'analyse : {str(e)}"
223
-
224
- # 🎨 INTERFACE SIMPLIFIÉE ET PROPRE
225
- with gr.Blocks(title="Analyseur de Vêtements", theme=gr.themes.Soft()) as demo:
226
-
227
- gr.Markdown("""
228
- # 👗 ANALYSEUR DE VÊTEMENTS
229
- *Reconnaissance précise basée sur une intelligence artificielle*
230
- """)
231
-
232
- with gr.Row():
233
- with gr.Column(scale=1):
234
- gr.Markdown("### 📤 UPLOADER UN VÊTEMENT")
235
- image_input = gr.Image(
236
- type="pil",
237
- label="Sélectionnez votre vêtement",
238
- height=300,
239
- sources=["upload"],
240
- )
241
-
242
- gr.Markdown("""
243
- ### 💡 CONSEILS :
244
- ✅ Photo nette et bien cadrée
245
- ✅ Fond uni de préférence
246
- ✅ Bon éclairage
247
- ✅ Un seul vêtement visible
248
- """)
249
-
250
- analyze_btn = gr.Button("🔍 Analyser le vêtement", variant="primary")
251
- clear_btn = gr.Button("🧹 Nouvelle image", variant="secondary")
252
-
253
- with gr.Column(scale=2):
254
- gr.Markdown("### 📊 RÉSULTATS DE L'ANALYSE")
255
- output_text = gr.Markdown(
256
- value="⬅️ Uploader un vêtement pour commencer l'analyse"
257
- )
258
-
259
- # 🎮 INTERACTIONS
260
- analyze_btn.click(
261
- fn=analyze_clothing,
262
- inputs=[image_input],
263
- outputs=output_text
264
- )
265
-
266
- clear_btn.click(
267
- fn=lambda: (None, "⬅️ Prêt pour une nouvelle analyse"),
268
- inputs=[],
269
- outputs=[image_input, output_text]
270
- )
271
-
272
- image_input.upload(
273
- fn=analyze_clothing,
274
- inputs=[image_input],
275
- outputs=output_text
276
- )
277
-
278
- # ⚙️ LANCEMENT
279
- if __name__ == "__main__":
280
- demo.launch(
281
- server_name="0.0.0.0",
282
- server_port=7860,
283
- share=False
284
- )
 
1
  import gradio as gr
2
+ from transformers import ViTImageProcessor, ViTForImageClassification
3
  from PIL import Image
4
+ import torch
5
+
6
+ # --- CHANGEMENT CRITIQUE : Charger VOTRE modèle fine-tuné ---
7
+ model_name = "MODLI/vit-fashion-classifier" # <--- REMPLACER par votre modèle entraîné
8
+ processor = ViTImageProcessor.from_pretrained(model_name)
9
+ model = ViTForImageClassification.from_pretrained(model_name)
10
+
11
+ # Fonction de prédiction avec seuil de confiance
12
+ def predict(image):
13
+ # Pré-traiter l'image exactement comme pendant l'entraînement
14
+ inputs = processor(images=image, return_tensors="pt")
15
+
16
+ # Prédire
17
+ with torch.no_grad():
18
+ outputs = model(**inputs)
19
+ logits = outputs.logits
20
+
21
+ # Appliquer softmax pour obtenir les probabilités
22
+ probabilities = torch.nn.functional.softmax(logits, dim=-1)[0]
23
+ top_probs, top_indices = torch.topk(probabilities, 5) # Top 5 predictions
24
+
25
+ # Formater les résultats
26
+ predictions = []
27
+ for i, (prob, idx) in enumerate(zip(top_probs, top_indices)):
28
+ pred_label = model.config.id2label[idx.item()]
29
+ confidence = prob.item()
30
+ # N'afficher que si la confiance est > 5%
31
+ if confidence > 0.05 or i == 0: # Toujours afficher la première même si faible
32
+ predictions.append((pred_label, f"{confidence:.2%}"))
33
+
34
+ return predictions
35
+
36
+ # Interface Gradio
37
+ title = "Fashion Item Classifier"
38
+ description = "Upload an image of a clothing item, and I will classify it."
39
+
40
+ demo = gr.Interface(
41
+ fn=predict,
42
+ inputs=gr.Image(type="pil", label="Upload Clothing Item"),
43
+ outputs=gr.Label(label="Predictions", num_top_classes=5),
44
+ title=title,
45
+ description=description,
46
+ examples=[["path_to_example_image_1.jpg"], ["path_to_example_image_2.jpg"]], # Ajoutez des exemples
47
+ )
48
+
49
+ demo.launch(debug=True)