import gradio as gr import tensorflow as tf import numpy as np from PIL import Image import json import requests import io import base64 import os os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # Disable GPU # ===== CONFIGURACIÓN ===== PLANTNET_CONFIG = { "base_url": "https://my-api.plantnet.org/v2/identify/all", "api_key": "2b10GtUDt6p1whX94wlEiR3CG", "timeout": 10, "lang": "es" # Español } # ===== VARIABLES GLOBALES ===== MODEL_LOADED = False model = None labels = [] # ===== FUNCIONES DE UTILIDAD ===== def load_model(): global model, labels, MODEL_LOADED try: model = tf.keras.models.load_model("flores_modelo (2).h5") with open("clases_orden_oxford.json", "r") as f: class_indices = json.load(f) labels = [None] * len(class_indices) for class_name, idx in class_indices.items(): labels[idx] = class_name.replace("_", " ").title() MODEL_LOADED = True except Exception as e: print(f"Error al cargar el modelo: {e}") MODEL_LOADED = False def image_to_base64(image_path): try: with open(image_path, "rb") as img_file: return base64.b64encode(img_file.read()).decode('utf-8') except: return None def preprocess_image(image): image = image.resize((224, 224)) img_array = np.array(image) / 255.0 if img_array.shape[-1] == 4: img_array = img_array[..., :3] return np.expand_dims(img_array, axis=0) # ===== INTEGRACIÓN CON PLANTNET ===== def get_flower_info_from_plantnet(flower_name, image_array): try: image_pil = Image.fromarray((image_array[0] * 255).astype(np.uint8)) img_byte_arr = io.BytesIO() image_pil.save(img_byte_arr, format='JPEG') img_byte_arr.seek(0) url = f"{PLANTNET_CONFIG['base_url']}?api-key={PLANTNET_CONFIG['api_key']}&lang={PLANTNET_CONFIG['lang']}" files = {'images': ('image.jpg', img_byte_arr, 'image/jpeg')} data = {'organs': 'flower'} response = requests.post(url, files=files, data=data, timeout=PLANTNET_CONFIG['timeout']) if response.status_code == 200: return parse_plantnet_response(response.json(), flower_name) else: print(f"Error en PlantNet: {response.status_code}") return get_fallback_info(flower_name) except requests.exceptions.Timeout: print("Tiempo de espera agotado en PlantNet") return get_fallback_info(flower_name) except Exception as e: print(f"PlantNet error: {e}") return get_fallback_info(flower_name) def parse_plantnet_response(data, flower_name): if 'results' in data and len(data['results']) > 0: results = data['results'][:3] info = f"""

🌸 {flower_name}

📊 Identificación Científica

""" for i, result in enumerate(results, 1): species = result.get('species', {}) scientific_name = species.get('scientificNameWithoutAuthor', 'N/A') authorship = species.get('scientificNameAuthorship', '') common_names = species.get('commonNames', []) family = species.get('family', {}).get('scientificNameWithoutAuthor', 'N/A') genus = species.get('genus', {}).get('scientificNameWithoutAuthor', 'N/A') score = result.get('score', 0) common_names_str = ', '.join(common_names[:3]) if common_names else 'No disponible' info += f"""
#{i}

{scientific_name} {authorship}

{score:.1%} confianza
Nombres comunes: {common_names_str}
Familia: {family}
Género: {genus}
""" info += """

🌿 Cuidados Generales

☀️
Luz: Luz solar directa o indirecta
💧
Riego: Mantener húmedo, evitar exceso
🌡️
Temperatura: Evitar cambios bruscos
🌱
Suelo: Bien drenado y rico en nutrientes
""" return info return get_fallback_info(flower_name) def get_fallback_info(flower_name): return f"""

🌸 {flower_name}

PlantNet no disponible

📖 Información General

Identificado por nuestro modelo de IA entrenado en el conjunto de datos Oxford 102 Flowers.

🌺 Características

  • Estructuras reproductivas de la planta
  • Varios colores y formas
  • Evolucionadas para atraer polinizadores

🎯 Cuidados Básicos

  • Buena iluminación según la especie
  • Riego regular sin exceso
  • Temperatura estable
  • Fertilización adecuada
""" # ===== LÓGICA DE PREDICCIÓN ===== def predict(image): if not image: return "No se cargó ninguna imagen", "0%", """

⚠️ Imagen requerida

Por favor, carga una imagen de una flor para iniciar la identificación.

""" if not MODEL_LOADED: return "Error en el modelo", "0%", """

🚫 Modelo no disponible

No se pudo cargar el modelo de clasificación. Verifica los archivos del modelo.

""" try: img_array = preprocess_image(image) preds = model.predict(img_array) class_idx = np.argmax(preds[0]) confidence = preds[0][class_idx] label_name = labels[class_idx] flower_details = get_flower_info_from_plantnet(label_name, img_array) return label_name, f"{confidence:.2%}", flower_details except Exception as e: return "Error", "0%", f"""

❌ Error de predicción

Error durante el procesamiento: {str(e)}

""" # ===== CSS PARA EL FONDO DE LA APLICACIÓN ===== custom_css = """ .gradio-container { background: #1E2A44; min-height: 100vh; } """ # ===== JAVASCRIPT PARA OPTIMIZACIÓN DE CÁMARA ===== camera_js_improved = """ """ # ===== APLICACIÓN PRINCIPAL ===== # Cargar el modelo al inicio load_model() img3_b64 = image_to_base64("img3.png") img2_b64 = image_to_base64("img2.png") with gr.Blocks(theme=gr.themes.Soft(), css=custom_css, title="🌸 Flower ") as demo: header_html = f'''
{'
Logo
' if img3_b64 else '
'}

IDENTIFICADOR DE FLORES

Identifica cualquier flor en cuestión de segundos

Oxford 102 Flowers + PlantNet

{'
Logo
' if img2_b64 else '
'}
''' gr.HTML(header_html) with gr.Row(): with gr.Column(scale=1): image_input = gr.Image(type="pil", label="📷 Cargar Imagen de Flor", height=350, sources=["upload", "webcam", "clipboard"]) predict_btn = gr.Button("🔍 Identificar Flor", variant="primary") gr.HTML(f'

📊 Estado del Sistema

Modelo: {"✅ Activo" if MODEL_LOADED else "❌ Error"}

Clases: {len(labels)}

') with gr.Column(scale=1): result_label = gr.Textbox(label="🌼 Flor Identificada", interactive=False, placeholder="El nombre de la flor aparecerá aquí...") result_conf = gr.Textbox(label="📊 Confianza", interactive=False, placeholder="El nivel de confianza aparecerá aquí...") flower_info_output = gr.HTML(value='

🌸 ¡Bienvenido!

Carga una imagen de una flor para iniciar la identificación.

') predict_btn.click(fn=predict, inputs=image_input, outputs=[result_label, result_conf, flower_info_output]) gr.HTML(camera_js_improved) if __name__ == "__main__": demo.launch(share=False)