| |
| """ |
| 🔬 Clasificador de Insectos Polinizadores - Versión de Producción |
| Precisión alcanzada: 92.07% |
| Modelo: YOLOv8 Nano |
| """ |
|
|
| from ultralytics import YOLO |
| import sys |
| import os |
| from pathlib import Path |
|
|
| class PollinatorClassifier: |
| def __init__(self, model_path="pollinator_results/nano_quick/weights/best.pt"): |
| """Inicializar el clasificador""" |
| try: |
| self.model = YOLO(model_path) |
| self.classes = [ |
| 'Acmaeodera Flavomarginata', 'Acromyrmex Octospinosus', |
| 'Adelpha Basiloides', 'Adelpha Iphicleola', 'Aedes Aegypti', |
| 'Agrius Cingulata', 'Anaea Aidea', 'Anartia fatima', |
| 'Anartia jatrophae', 'Anoplolepis Gracilipes' |
| ] |
| print("🔬 Clasificador de Insectos Polinizadores v1.0") |
| print(f"✅ Modelo cargado con 92.07% de precisión") |
| print(f"🏷️ {len(self.classes)} clases disponibles") |
|
|
| except Exception as e: |
| print(f"❌ Error cargando modelo: {e}") |
| sys.exit(1) |
|
|
| def classify(self, image_path): |
| """Clasificar una imagen de insecto""" |
|
|
| if not os.path.exists(image_path): |
| print(f"❌ Imagen no encontrada: {image_path}") |
| return None |
|
|
| |
| results = self.model(image_path, verbose=False) |
| probs = results[0].probs |
|
|
| |
| top_class_idx = probs.top1 |
| confidence = probs.top1conf.item() * 100 |
| predicted_class = self.classes[top_class_idx] |
|
|
| print(f"\n🔍 Imagen: {os.path.basename(image_path)}") |
| print(f"🎯 Predicción: {predicted_class}") |
| print(f"📊 Confianza: {confidence:.1f}%") |
|
|
| |
| print(f"\n📋 Top 3 predicciones:") |
| for i in range(min(3, len(probs.top5))): |
| idx = probs.top5[i] |
| conf = probs.top5conf[i].item() * 100 |
| class_name = self.classes[idx] |
| emoji = "🥇" if i == 0 else "🥈" if i == 1 else "🥉" |
| print(f" {emoji} {class_name}: {conf:.1f}%") |
|
|
| return predicted_class, confidence |
|
|
| def classify_batch(self, folder_path): |
| """Clasificar múltiples imágenes en una carpeta""" |
|
|
| folder = Path(folder_path) |
| if not folder.exists(): |
| print(f"❌ Carpeta no encontrada: {folder_path}") |
| return |
|
|
| |
| image_extensions = ['*.jpg', '*.jpeg', '*.png', '*.JPG', '*.JPEG', '*.PNG'] |
| images = [] |
| for ext in image_extensions: |
| images.extend(list(folder.glob(ext))) |
|
|
| if not images: |
| print("❌ No se encontraron imágenes") |
| return |
|
|
| print(f"🔍 Clasificando {len(images)} imágenes...") |
| print("-" * 60) |
|
|
| results = [] |
| for img_path in images: |
| pred_class, confidence = self.classify(str(img_path)) |
| if pred_class: |
| results.append({ |
| 'imagen': img_path.name, |
| 'prediccion': pred_class, |
| 'confianza': confidence |
| }) |
|
|
| return results |
|
|
| def main(): |
| """Función principal""" |
| classifier = PollinatorClassifier() |
|
|
| if len(sys.argv) < 2: |
| |
| print("\n🎯 MODO INTERACTIVO") |
| print("Opciones:") |
| print("1. Clasificar una imagen") |
| print("2. Clasificar carpeta de imágenes") |
|
|
| choice = input("\nSelecciona opción (1 o 2): ") |
|
|
| if choice == "1": |
| image_path = input("Ruta de la imagen: ") |
| classifier.classify(image_path) |
| elif choice == "2": |
| folder_path = input("Ruta de la carpeta: ") |
| classifier.classify_batch(folder_path) |
| else: |
| print("Opción inválida") |
| else: |
| |
| path = sys.argv[1] |
| if os.path.isfile(path): |
| classifier.classify(path) |
| elif os.path.isdir(path): |
| classifier.classify_batch(path) |
| else: |
| print(f"❌ Ruta inválida: {path}") |
|
|
| if __name__ == "__main__": |
| main() |
|
|