import gradio as gr import tensorflow as tf import numpy as np from PIL import Image import json from huggingface_hub import hf_hub_download # ============================================ # Configurações do modelo # ============================================ REPO_ID = "raysarocha/plant-resnet50-38classes" # Seu modelo recém-deployado! # ============================================ # Carregamento do modelo # ============================================ def load_model(): """Carrega o modelo uma única vez e mantém em cache""" print("🔄 Baixando e carregando modelo...") # Baixa os arquivos cfg_path = hf_hub_download(REPO_ID, "config.json") model_path = hf_hub_download(REPO_ID, "model.keras") # Carrega configuração with open(cfg_path, "r") as f: cfg = json.load(f) # Carrega modelo model = tf.keras.models.load_model(model_path) print("✅ Modelo carregado com sucesso!") return model, cfg # Carrega o modelo model, cfg = load_model() # ============================================ # Dicionário de nomes amigáveis e recomendações # ============================================ PLANT_INFO = { "Apple___Apple_scab": { "name": "🍎 Maçã - Sarna", "healthy": False, "description": "Doença fúngica que causa manchas escuras nas folhas e frutos", "treatment": "• Remova folhas infectadas\n• Aplique fungicida à base de cobre\n• Melhore a circulação de ar" }, "Apple___Black_rot": { "name": "🍎 Maçã - Podridão Negra", "healthy": False, "description": "Infecção fúngica que causa podridão em frutos e folhas", "treatment": "• Pode galhos infectados\n• Remova frutos mumificados\n• Use fungicida preventivo" }, "Apple___Cedar_apple_rust": { "name": "🍎 Maçã - Ferrugem do Cedro", "healthy": False, "description": "Doença que causa manchas alaranjadas nas folhas", "treatment": "• Remova cedros próximos se possível\n• Aplique fungicida na primavera\n• Escolha variedades resistentes" }, "Apple___healthy": { "name": "🍎 Maçã - Saudável", "healthy": True, "description": "Planta em bom estado de saúde", "treatment": "• Continue com os cuidados regulares\n• Mantenha boa irrigação\n• Faça podas preventivas" }, "Tomato___Bacterial_spot": { "name": "🍅 Tomate - Mancha Bacteriana", "healthy": False, "description": "Infecção bacteriana que causa manchas nas folhas", "treatment": "• Evite molhar as folhas\n• Use sementes certificadas\n• Aplique cobre preventivamente" }, "Tomato___Early_blight": { "name": "🍅 Tomate - Requeima Precoce", "healthy": False, "description": "Doença fúngica com manchas em anéis concêntricos", "treatment": "• Remova folhas afetadas\n• Aplique fungicida\n• Faça rotação de culturas" }, "Tomato___healthy": { "name": "🍅 Tomate - Saudável", "healthy": True, "description": "Planta em bom estado de saúde", "treatment": "• Mantenha irrigação regular\n• Adube adequadamente\n• Monitore pragas" }, "Potato___Early_blight": { "name": "🥔 Batata - Requeima Precoce", "healthy": False, "description": "Manchas escuras com anéis concêntricos nas folhas", "treatment": "• Use fungicida preventivo\n• Evite irrigação excessiva\n• Destrua restos culturais" }, "Potato___Late_blight": { "name": "🥔 Batata - Requeima Tardia", "healthy": False, "description": "Doença devastadora que causa manchas aquosas", "treatment": "• Aplique fungicida imediatamente\n• Remova plantas infectadas\n• Melhore drenagem do solo" }, "Potato___healthy": { "name": "🥔 Batata - Saudável", "healthy": True, "description": "Planta em bom estado de saúde", "treatment": "• Continue monitorando\n• Faça amontoa regular\n• Controle irrigação" } } # Preenche informações padrão para classes não detalhadas for class_key in cfg["label2id"].keys(): if class_key not in PLANT_INFO: if "healthy" in class_key.lower(): PLANT_INFO[class_key] = { "name": class_key.replace("___", " - ").replace("_", " "), "healthy": True, "description": "Planta aparentemente saudável", "treatment": "• Mantenha os cuidados regulares\n• Continue monitorando" } else: PLANT_INFO[class_key] = { "name": class_key.replace("___", " - ").replace("_", " "), "healthy": False, "description": "Possível problema detectado na planta", "treatment": "• Consulte um agrônomo\n• Isole a planta se possível\n• Evite excesso de umidade" } # ============================================ # Função de classificação # ============================================ def classify_plant(image): """Classifica a imagem e retorna diagnóstico detalhado""" if image is None: return None, "", "" # Preprocessamento img = Image.fromarray(image).convert("RGB") img = img.resize((cfg["image_size"], cfg["image_size"])) arr = np.array(img).astype("float32") * cfg["rescale"] arr = np.expand_dims(arr, axis=0) # Predição predictions = model(arr) probs = tf.nn.softmax(predictions[0]).numpy() # Top 5 resultados top_5_idx = np.argsort(probs)[-5:][::-1] # Formata resultados results = {} for idx in top_5_idx: class_name = cfg["id2label"][str(idx)] info = PLANT_INFO.get(class_name, {}) friendly_name = info.get("name", class_name) confidence = float(probs[idx]) results[friendly_name] = confidence # Pega informação da classe mais provável top_class = cfg["id2label"][str(top_5_idx[0])] top_confidence = float(probs[top_5_idx[0]]) top_info = PLANT_INFO.get(top_class, {}) # Cria card de diagnóstico if top_info.get("healthy", False): status_icon = "✅" status_text = "Planta Saudável" card_color = "#10b981" # Verde bg_color = "#f0fdf4" else: status_icon = "⚠️" status_text = "Atenção Necessária" card_color = "#f59e0b" # Laranja bg_color = "#fef3c7" diagnosis_html = f"""
Confiança: {top_confidence:.1%}
Descrição:
{top_info.get('description', 'Informação não disponível')}
{top_info.get('treatment', '• Consulte um especialista para orientações específicas')}
Faça upload de uma foto para começar
Desenvolvido com ❤️ por Raysa Rocha | 2024
""") # Eventos submit_btn.click( fn=classify_plant, inputs=input_image, outputs=[confidence_output, diagnosis_output, treatment_output] ) clear_btn.click( fn=lambda: (None, "