Mapu142 commited on
Commit
2bbbf2d
·
verified ·
1 Parent(s): fd42f91

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +375 -0
app.py ADDED
@@ -0,0 +1,375 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import pipeline, ViTImageProcessor, ViTForImageClassification, YolosImageProcessor, YolosForObjectDetection
3
+ from PIL import Image, ImageDraw
4
+ import torch
5
+ import numpy as np
6
+
7
+ class UniversalImageClassifier:
8
+ def __init__(self):
9
+ print("🔄 Cargando clasificador de imágenes ViT...")
10
+ self.model_name = "google/vit-base-patch16-224"
11
+ self.processor = ViTImageProcessor.from_pretrained(self.model_name)
12
+ self.model = ViTForImageClassification.from_pretrained(self.model_name)
13
+
14
+ self.classifier = pipeline(
15
+ "image-classification",
16
+ model=self.model,
17
+ feature_extractor=self.processor,
18
+ device=-1 # CPU
19
+ )
20
+
21
+ print("✅ Clasificador ViT cargado!")
22
+
23
+ self.category_mappings = {
24
+ 'egyptian_cat': '🐱 Gato Egipcio',
25
+ 'tabby': '🐱 Gato Atigrado',
26
+ 'tiger_cat': '🐱 Gato Tiger',
27
+ 'golden_retriever': '🐕 Golden Retriever',
28
+ 'german_shepherd': '🐕 Pastor Alemán',
29
+ 'beagle': '🐕 Beagle',
30
+ 'sports_car': '🏎️ Auto Deportivo',
31
+ 'convertible': '🚗 Convertible',
32
+ 'motorcycle': '🏍️ Motocicleta',
33
+ 'bicycle': '🚲 Bicicleta',
34
+ 'airplane': '✈️ Avión',
35
+ 'pizza': '🍕 Pizza',
36
+ 'hamburger': '🍔 Hamburguesa',
37
+ 'hot_dog': '🌭 Hot Dog',
38
+ 'ice_cream': '🍦 Helado',
39
+ 'laptop': '💻 Laptop',
40
+ 'cellular_telephone': '📱 Teléfono Móvil',
41
+ 'television': '📺 Televisión',
42
+ 'daisy': '🌼 Margarita',
43
+ 'rose': '🌹 Rosa',
44
+ 'sunflower': '🌻 Girasol',
45
+ }
46
+
47
+ def classify_image(self, image):
48
+ try:
49
+ results = self.classifier(image)
50
+ predictions = []
51
+ for result in results[:5]:
52
+ label = result['label']
53
+ confidence = result['score'] * 100
54
+ display_label = self.category_mappings.get(label, f"🔍 {label.replace('_', ' ').title()}")
55
+
56
+ predictions.append({
57
+ 'label': display_label,
58
+ 'original_label': label,
59
+ 'confidence': confidence
60
+ })
61
+
62
+ return predictions
63
+ except Exception as e:
64
+ return [{'label': f'Error: {str(e)}', 'confidence': 0}]
65
+
66
+ class ObjectDetector:
67
+ def __init__(self):
68
+ print("🔄 Cargando detector de objetos YOLOS...")
69
+ self.model_name = "hustvl/yolos-tiny"
70
+ self.processor = YolosImageProcessor.from_pretrained(self.model_name)
71
+ self.model = YolosForObjectDetection.from_pretrained(self.model_name)
72
+
73
+ print("✅ Detector YOLOS cargado!")
74
+
75
+ self.class_mappings = {
76
+ 'person': '👤 Persona',
77
+ 'bicycle': '🚲 Bicicleta',
78
+ 'car': '🚗 Auto',
79
+ 'motorcycle': '🏍️ Motocicleta',
80
+ 'airplane': '✈️ Avión',
81
+ 'bus': '🚌 Autobús',
82
+ 'train': '🚂 Tren',
83
+ 'truck': '🚛 Camión',
84
+ 'boat': '⛵ Barco',
85
+ 'traffic light': '🚦 Semáforo',
86
+ 'bird': '🐦 Pájaro',
87
+ 'cat': '🐱 Gato',
88
+ 'dog': '🐕 Perro',
89
+ 'horse': '🐎 Caballo',
90
+ 'elephant': '🐘 Elefante',
91
+ 'backpack': '🎒 Mochila',
92
+ 'umbrella': '☂️ Paraguas',
93
+ 'bottle': '🍼 Botella',
94
+ 'cup': '☕ Taza',
95
+ 'banana': '🍌 Plátano',
96
+ 'apple': '🍎 Manzana',
97
+ 'pizza': '🍕 Pizza',
98
+ 'chair': '🪑 Silla',
99
+ 'couch': '🛋️ Sofá',
100
+ 'bed': '🛏️ Cama',
101
+ 'tv': '📺 Televisión',
102
+ 'laptop': '💻 Laptop',
103
+ 'mouse': '🖱️ Mouse',
104
+ 'cell phone': '📱 Teléfono',
105
+ 'book': '📚 Libro',
106
+ 'clock': '🕐 Reloj'
107
+ }
108
+
109
+ def detect_objects(self, image):
110
+ try:
111
+ inputs = self.processor(images=image, return_tensors="pt")
112
+ outputs = self.model(**inputs)
113
+
114
+ target_sizes = torch.tensor([image.size[::-1]])
115
+ results = self.processor.post_process_object_detection(
116
+ outputs, target_sizes=target_sizes, threshold=0.3
117
+ )[0]
118
+
119
+ detections = []
120
+ for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
121
+ if score > 0.3:
122
+ label_name = self.model.config.id2label[label.item()]
123
+ display_name = self.class_mappings.get(label_name, f"🔍 {label_name}")
124
+
125
+ detections.append({
126
+ 'label': display_name,
127
+ 'original_label': label_name,
128
+ 'confidence': score.item() * 100,
129
+ 'box': box.tolist()
130
+ })
131
+
132
+ return detections
133
+ except Exception as e:
134
+ return [{'label': f'Error: {str(e)}', 'confidence': 0, 'box': [0, 0, 0, 0]}]
135
+
136
+ def draw_detections(self, image, detections):
137
+ try:
138
+ annotated_image = image.copy()
139
+ draw = ImageDraw.Draw(annotated_image)
140
+
141
+ colors = ['red', 'blue', 'green', 'yellow', 'purple', 'orange', 'cyan', 'magenta']
142
+
143
+ for i, detection in enumerate(detections):
144
+ if detection['confidence'] > 30:
145
+ box = detection['box']
146
+ label = detection['label']
147
+ confidence = detection['confidence']
148
+
149
+ xmin, ymin, xmax, ymax = box
150
+ color = colors[i % len(colors)]
151
+
152
+ draw.rectangle([(xmin, ymin), (xmax, ymax)], outline=color, width=3)
153
+
154
+ text = f"{label} ({confidence:.1f}%)"
155
+ try:
156
+ text_bbox = draw.textbbox((0, 0), text)
157
+ text_width = text_bbox[2] - text_bbox[0]
158
+ text_height = text_bbox[3] - text_bbox[1]
159
+
160
+ draw.rectangle(
161
+ [(xmin, ymin - text_height - 4), (xmin + text_width + 4, ymin)],
162
+ fill=color
163
+ )
164
+ draw.text((xmin + 2, ymin - text_height - 2), text, fill='white')
165
+ except:
166
+ draw.text((xmin, ymin - 20), text, fill=color)
167
+
168
+ return annotated_image
169
+ except Exception as e:
170
+ return image
171
+
172
+ # Inicializar modelos
173
+ print("🚀 Inicializando modelos de IA...")
174
+ classifier = UniversalImageClassifier()
175
+ detector = ObjectDetector()
176
+ print("✅ ¡Todos los modelos listos!")
177
+
178
+ def classify_image_complete(image):
179
+ if image is None:
180
+ return "❌ Por favor sube una imagen para clasificar"
181
+
182
+ try:
183
+ predictions = classifier.classify_image(image)
184
+
185
+ if not predictions or predictions[0]['confidence'] == 0:
186
+ return "❌ No se pudo clasificar la imagen"
187
+
188
+ dominant = predictions[0]
189
+
190
+ report = f"""# 🔍 Clasificación de Imagen
191
+ ## 🎯 Predicción Principal:
192
+ ### {dominant['label']}
193
+ **Confianza:** {dominant['confidence']:.1f}%
194
+ ## 📊 Top 5 Predicciones:
195
+ """
196
+
197
+ for i, pred in enumerate(predictions, 1):
198
+ bar = "█" * int(pred['confidence'] / 10) + "░" * (10 - int(pred['confidence'] / 10))
199
+ report += f"\n**{i}.** {pred['label']}\n{bar} {pred['confidence']:.1f}%"
200
+
201
+ # Análisis de confianza
202
+ confidence = dominant['confidence']
203
+ if confidence > 80:
204
+ level = "🟢 Muy Alta"
205
+ elif confidence > 60:
206
+ level = "🟡 Alta"
207
+ elif confidence > 40:
208
+ level = "🟠 Moderada"
209
+ else:
210
+ level = "🔴 Baja"
211
+
212
+ report += f"\n\n## 🎚️ Confianza: {level}"
213
+ report += f"\n\n*Clasificación con Vision Transformer (ViT)*"
214
+
215
+ return report
216
+
217
+ except Exception as e:
218
+ return f"❌ Error: {str(e)}"
219
+
220
+ def detect_objects_complete(image):
221
+ if image is None:
222
+ return "❌ Por favor sube una imagen para detectar objetos", None
223
+
224
+ try:
225
+ detections = detector.detect_objects(image)
226
+
227
+ if not detections or detections[0]['confidence'] == 0:
228
+ return "❌ No se detectaron objetos", image
229
+
230
+ annotated_image = detector.draw_detections(image, detections)
231
+
232
+ object_counts = {}
233
+ for detection in detections:
234
+ if detection['confidence'] > 30:
235
+ label = detection['original_label']
236
+ object_counts[label] = object_counts.get(label, 0) + 1
237
+
238
+ total_objects = len(detections)
239
+ unique_objects = len(object_counts)
240
+
241
+ report = f"""# 🎯 Detección de Objetos
242
+ ## 📊 Resumen:
243
+ - **Objetos detectados:** {total_objects}
244
+ - **Tipos únicos:** {unique_objects}
245
+ - **Confianza promedio:** {np.mean([d['confidence'] for d in detections]):.1f}%
246
+ ## 🔍 Objetos Encontrados:
247
+ """
248
+
249
+ sorted_detections = sorted(detections, key=lambda x: x['confidence'], reverse=True)
250
+
251
+ for i, detection in enumerate(sorted_detections[:10], 1): # Top 10
252
+ label = detection['label']
253
+ confidence = detection['confidence']
254
+ bar = "█" * int(confidence / 10) + "░" * (10 - int(confidence / 10))
255
+
256
+ report += f"\n**{i}.** {label}\n{bar} {confidence:.1f}%"
257
+
258
+ report += f"\n\n## 📈 Conteo por Tipo:"
259
+ for obj_type, count in sorted(object_counts.items(), key=lambda x: x[1], reverse=True)[:5]:
260
+ display_name = detector.class_mappings.get(obj_type, obj_type)
261
+ report += f"\n- {display_name}: **{count}**"
262
+
263
+ report += f"\n\n*Detección con YOLOS (You Only Look Once)*"
264
+
265
+ return report, annotated_image
266
+
267
+ except Exception as e:
268
+ return f"❌ Error: {str(e)}", None
269
+
270
+ # Interfaz Gradio
271
+ with gr.Blocks(title="🤖 Analizador Visual Universal con IA") as demo:
272
+
273
+ gr.Markdown("""
274
+ # 🤖 Analizador Visual Universal con IA
275
+
276
+ **Dos poderosos modelos de IA en una sola aplicación**
277
+
278
+ 🔍 **Clasificador Universal:** Identifica QUÉ ES (1000+ categorías)
279
+ 🎯 **Detector de Objetos:** Encuentra DÓNDE ESTÁN (80+ objetos)
280
+
281
+ ✨ **Modelos incluidos:**
282
+ - 🧠 Vision Transformer (ViT) de Google
283
+ - 🎯 YOLOS (You Only Look Once)
284
+ - 💻 100% optimizado para CPU
285
+ """)
286
+
287
+ with gr.Tabs():
288
+ # Tab 1: Clasificador
289
+ with gr.Tab("🔍 Clasificador Universal"):
290
+ gr.Markdown("""
291
+ ### Identifica automáticamente el contenido principal de tu imagen
292
+ **Perfecto para:** Catalogar fotos, identificar objetos desconocidos, análisis de contenido
293
+ """)
294
+
295
+ with gr.Row():
296
+ with gr.Column(scale=1):
297
+ classify_input = gr.Image(
298
+ label="📸 Sube tu imagen",
299
+ type="pil"
300
+ )
301
+ classify_btn = gr.Button(
302
+ "🚀 Clasificar Imagen",
303
+ variant="primary",
304
+ size="lg"
305
+ )
306
+
307
+ with gr.Column(scale=2):
308
+ classify_output = gr.Markdown(
309
+ label="📋 Resultado de Clasificación"
310
+ )
311
+
312
+ # gr.Examples(
313
+ # examples=[
314
+ # "https://images.unsplash.com/photo-1574158622682-e40e69881006?w=300", # Gato
315
+ # "https://images.unsplash.com/photo-1552053831-71594a27632d?w=300", # Perro
316
+ # "https://images.unsplash.com/photo-1565299624946-b28f40a0ca4b?w=300" # Pizza
317
+ # ],
318
+ # inputs=[classify_input],
319
+ # label="🖼️ Ejemplos para probar"
320
+ # )
321
+
322
+ # Tab 2: Detector de Objetos
323
+ with gr.Tab("🎯 Detector de Objetos"):
324
+ gr.Markdown("""
325
+ ### Encuentra y localiza múltiples objetos en tu imagen
326
+ **Perfecto para:** Análisis de escenas, inventarios visuales, seguridad
327
+ """)
328
+
329
+ with gr.Row():
330
+ with gr.Column(scale=1):
331
+ detect_input = gr.Image(
332
+ label="📸 Sube tu imagen",
333
+ type="pil"
334
+ )
335
+ detect_btn = gr.Button(
336
+ "🎯 Detectar Objetos",
337
+ variant="primary",
338
+ size="lg"
339
+ )
340
+
341
+ with gr.Column(scale=1):
342
+ detect_output = gr.Markdown(
343
+ label="📋 Objetos Detectados"
344
+ )
345
+ detect_image_output = gr.Image(
346
+ label="🎯 Imagen Anotada",
347
+ type="pil"
348
+ )
349
+
350
+ # Eventos
351
+ classify_btn.click(
352
+ classify_image_complete,
353
+ inputs=[classify_input],
354
+ outputs=[classify_output]
355
+ )
356
+
357
+ detect_btn.click(
358
+ detect_objects_complete,
359
+ inputs=[detect_input],
360
+ outputs=[detect_output, detect_image_output]
361
+ )
362
+
363
+ gr.Markdown("""
364
+ ---
365
+ ### 💡 Consejos para mejores resultados:
366
+ - Usa imágenes claras y bien iluminadas
367
+ - Centra el objeto principal para clasificación
368
+ - Para detección, incluye múltiples objetos en la escena
369
+ - Resolución mínima recomendada: 224x224 píxeles
370
+
371
+ **🚀 Powered by Hugging Face Transformers**
372
+ """)
373
+
374
+ if __name__ == "__main__":
375
+ demo.launch()