import gradio as gr import torch import torch.nn as nn from torchvision import transforms, models from PIL import Image DEVICE = torch.device("cpu") MODEL_PATH = "plant_disease_mvp.pth" TREATMENTS = { "Apple___Apple_scab": ["Appliquer un fongicide à base de captane ou myclobutanil", "Ramasser et détruire les feuilles tombées", "Tailler pour améliorer la circulation d'air"], "Apple___Black_rot": ["Tailler et brûler les branches infectées", "Appliquer un fongicide à base de cuivre au printemps", "Désinfecter les outils de taille"], "Apple___Cedar_apple_rust": ["Utiliser un fongicide à base de myclobutanil", "Éviter de planter près des cèdres", "Traiter dès l'apparition des premiers symptômes"], "Apple___healthy": ["Plante saine — aucun traitement nécessaire", "Maintenir les bonnes pratiques d'irrigation", "Surveiller régulièrement les feuilles"], "Blueberry___healthy": ["Plante saine — aucun traitement nécessaire", "Maintenir un bon drainage du sol"], "Cherry_(including_sour)___Powdery_mildew": ["Appliquer du soufre en poudre ou fongicide soufré", "Améliorer la circulation de l'air autour de l'arbre", "Éviter l'excès d'azote dans les engrais"], "Cherry_(including_sour)___healthy": ["Plante saine — aucun traitement nécessaire", "Continuer les bonnes pratiques agricoles"], "Corn_(maize)___Cercospora_leaf_spot Gray_leaf_spot": ["Utiliser des variétés résistantes à la maladie", "Appliquer un fongicide à base de strobilurine", "Pratiquer la rotation des cultures"], "Corn_(maize)___Common_rust_": ["Appliquer un fongicide préventif dès les premiers signes", "Utiliser des semences résistantes", "Détruire les résidus de récolte infectés"], "Corn_(maize)___Northern_Leaf_Blight": ["Appliquer un fongicide systémique (propiconazole)", "Pratiquer la rotation des cultures", "Utiliser des hybrides résistants"], "Corn_(maize)___healthy": ["Plante saine — aucun traitement nécessaire", "Continuer les bonnes pratiques agricoles"], "Grape___Black_rot": ["Tailler les parties infectées et les brûler", "Appliquer un fongicide à base de mancozèbe", "Éliminer les baies momifiées sur la vigne"], "Grape___Esca_(Black_Measles)": ["Tailler les bois infectés en période sèche", "Protéger les plaies avec un produit cicatrisant", "Éviter le stress hydrique de la vigne"], "Grape___Leaf_blight_(Isariopsis_Leaf_Spot)": ["Appliquer un fongicide cuivrique", "Améliorer la ventilation du vignoble", "Éliminer les feuilles tombées infectées"], "Grape___healthy": ["Plante saine — aucun traitement nécessaire", "Continuer les bonnes pratiques viticoles"], "Orange___Haunglongbing_(Citrus_greening)": ["Maladie grave sans traitement curatif", "Arracher et détruire les arbres infectés immédiatement", "Contrôler le psylle asiatique (insecticide)"], "Peach___Bacterial_spot": ["Appliquer un bactéricide à base de cuivre", "Éviter les blessures sur les fruits et rameaux", "Tailler en période sèche et désinfecter les outils"], "Peach___healthy": ["Plante saine — aucun traitement nécessaire", "Continuer les bonnes pratiques agricoles"], "Pepper,_bell___Bacterial_spot": ["Appliquer un bactéricide cuivrique dès les premiers symptômes", "Éviter l'irrigation par aspersion", "Éliminer et détruire les plants très infectés"], "Pepper,_bell___healthy": ["Plante saine — aucun traitement nécessaire", "Maintenir un bon drainage du sol"], "Potato___Early_blight": ["Appliquer un fongicide à base de chlorothalonil", "Pratiquer la rotation des cultures (3 ans minimum)", "Éliminer les feuilles infectées du champ"], "Potato___Late_blight": ["Traitement urgent avec fongicide systémique (métalaxyl)", "Détruire immédiatement les plants très infectés", "Ne pas composter les tubercules infectés"], "Potato___healthy": ["Plante saine — aucun traitement nécessaire", "Surveiller régulièrement pour détecter tôt"], "Raspberry___healthy": ["Plante saine — aucun traitement nécessaire", "Continuer les bonnes pratiques agricoles"], "Soybean___healthy": ["Plante saine — aucun traitement nécessaire", "Maintenir la rotation des cultures"], "Squash___Powdery_mildew": ["Appliquer du bicarbonate de soude dilué (1%) en spray", "Utiliser un fongicide soufré si sévère", "Améliorer la circulation d'air entre les plants"], "Strawberry___Leaf_scorch": ["Appliquer un fongicide à base de captan", "Éviter l'excès d'humidité sur les feuilles", "Éliminer les feuilles infectées du champ"], "Strawberry___healthy": ["Plante saine — aucun traitement nécessaire", "Continuer les bonnes pratiques agricoles"], "Tomato___Bacterial_spot": ["Appliquer un bactéricide à base de cuivre", "Éviter l'arrosage sur les feuilles", "Éliminer et brûler les plants très infectés"], "Tomato___Early_blight": ["Appliquer un fongicide à base de chlorothalonil", "Éliminer les feuilles infectées en bas de la plante", "Éviter l'excès d'humidité au niveau du sol"], "Tomato___Late_blight": ["Traitement urgent avec fongicide systémique", "Détruire les plants très infectés immédiatement", "Éviter l'irrigation par aspersion"], "Tomato___Leaf_Mold": ["Améliorer la ventilation de la serre ou du champ", "Appliquer un fongicide à base de mancozèbe", "Réduire l'humidité relative autour des plants"], "Tomato___Septoria_leaf_spot": ["Appliquer un fongicide (chlorothalonil ou cuivre)", "Éviter d'arroser le feuillage directement", "Éliminer les feuilles infectées régulièrement"], "Tomato___Spider_mites Two-spotted_spider_mite": ["Appliquer un acaricide homologué", "Augmenter l'humidité autour des plants", "Introduire des prédateurs naturels (acariens utiles)"], "Tomato___Target_Spot": ["Appliquer un fongicide systémique (azoxystrobine)", "Éliminer les débris végétaux du sol", "Pratiquer la rotation des cultures"], "Tomato___Tomato_Yellow_Leaf_Curl_Virus": ["Maladie virale sans traitement curatif", "Contrôler les aleurodes (mouches blanches) vecteurs", "Arracher et détruire les plants infectés"], "Tomato___Tomato_mosaic_virus": ["Pas de traitement curatif disponible", "Désinfecter tous les outils de travail (eau de javel)", "Arracher et détruire les plants infectés"], "Tomato___healthy": ["Plante saine — aucun traitement nécessaire", "Continuer les bonnes pratiques agricoles", "Surveiller régulièrement les feuilles"], } def load_model(model_path): checkpoint = torch.load(model_path, map_location=DEVICE) class_names = checkpoint["class_names"] num_classes = checkpoint["num_classes"] model = models.mobilenet_v2(pretrained=False) model.classifier = nn.Sequential( nn.Dropout(p=0.3), nn.Linear(model.last_channel, num_classes) ) model.load_state_dict(checkpoint["model_state_dict"]) model.eval() return model, class_names model, CLASS_NAMES = load_model(MODEL_PATH) transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) def predict(image): if image is None: return "", "", "" img_tensor = transform(image).unsqueeze(0).to(DEVICE) with torch.no_grad(): outputs = model(img_tensor) probs = torch.softmax(outputs, dim=1) conf, idx = probs.max(1) pred_class = CLASS_NAMES[idx.item()] confidence = conf.item() * 100 parts = pred_class.split("___") plant = parts[0].replace("_", " ") disease = parts[1].replace("_", " ") if len(parts) > 1 else "Inconnue" is_healthy = "healthy" in pred_class.lower() status = "SAINE" if is_healthy else "MALADE" color = "#2d6a4f" if is_healthy else "#c1121f" bg_color = "#e8f5e9" if is_healthy else "#fdecea" icon = "✅" if is_healthy else "⚠️" conf_bar = int(confidence) result_html = f"""
Diagnostic intelligent par IA · MobileNetV2 · 96.59% de précision sur 38 classes
📸 Image de la plante
') image_input = gr.Image(type="pil", label="", height=300) predict_btn = gr.Button("🔍 Analyser la plante", variant="primary", size="lg") gr.HTML('Formats acceptés : JPG · PNG · WEBP
') with gr.Column(scale=1): result_out = gr.HTML() treatment_out = gr.HTML() top3_out = gr.HTML() predict_btn.click(fn=predict, inputs=image_input, outputs=[result_out, treatment_out, top3_out]) gr.HTML("""