CropScan
Plant disease detection
#!/usr/bin/env python3 """ CropScan - Plant Disease Detection Hugging Face Space Demo """ import gradio as gr import numpy as np from PIL import Image from pathlib import Path import torch # Model paths MODEL_DIR = Path("models") RFDETR_CHECKPOINT = MODEL_DIR / "rfdetr" / "checkpoint_best_total.pth" SAM2_CHECKPOINT = MODEL_DIR / "sam2" / "sam2.1_hiera_small.pt" # Lazy loaded components segmenter = None leaf_segmenter = None # Clean CSS - green theme, no effects CUSTOM_CSS = """ .gradio-container { background: #0d1117 !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } .main-header { text-align: center; padding: 1.5rem 0; border-bottom: 1px solid #21262d; margin-bottom: 1.5rem; } .main-header h1 { font-size: 2rem; font-weight: 600; color: #3fb950; margin: 0; } .main-header p { color: #8b949e; margin-top: 0.25rem; font-size: 0.9rem; } .section-label { color: #c9d1d9; font-size: 0.875rem; font-weight: 500; margin-bottom: 0.75rem; } .result-box { background: #161b22; border: 1px solid #30363d; border-radius: 8px; padding: 1rem; color: #c9d1d9; } .healthy-status { background: #0d1117; border: 1px solid #238636; border-radius: 6px; padding: 1rem; margin-bottom: 1rem; } .healthy-status h4 { color: #3fb950; margin: 0 0 0.25rem 0; font-size: 1rem; } .warning-status { background: #0d1117; border: 1px solid #9e6a03; border-radius: 6px; padding: 1rem; margin-bottom: 1rem; } .warning-status h4 { color: #d29922; margin: 0 0 0.25rem 0; font-size: 1rem; } .danger-status { background: #0d1117; border: 1px solid #da3633; border-radius: 6px; padding: 1rem; margin-bottom: 1rem; } .danger-status h4 { color: #f85149; margin: 0 0 0.25rem 0; font-size: 1rem; } button.primary { background: #238636 !important; border: none !important; } button.primary:hover { background: #2ea043 !important; } input[type="range"] { accent-color: #238636 !important; } input[type="checkbox"] { accent-color: #238636 !important; } .footer-text { text-align: center; color: #484f58; font-size: 0.8rem; padding: 1rem; border-top: 1px solid #21262d; margin-top: 1rem; } .examples-title { color: #3fb950 !important; font-size: 1.1rem !important; font-weight: 600 !important; margin-bottom: 1rem !important; } .gallery img { height: 120px !important; width: auto !important; object-fit: cover !important; } footer { display: none !important; } """ def load_models(): """Load models on first use.""" global segmenter, leaf_segmenter if segmenter is not None: return print("Loading models...") from src.sam3_segmentation import RFDETRSegmenter from src.leaf_segmenter import SAM2LeafSegmenter segmenter = RFDETRSegmenter( checkpoint_path=str(RFDETR_CHECKPOINT), model_size="medium" ) leaf_segmenter = SAM2LeafSegmenter( checkpoint_path=str(SAM2_CHECKPOINT) ) print("Models loaded!") def get_care_recommendations(num_detections: int, affected_percent: float) -> str: """Generate care recommendations based on detection results.""" if num_detections == 0: return """
No disease symptoms detected.
{affected_percent:.1f}% affected | {num_detections} region(s)
Plant disease detection
Examples - click to load
') example_images = [ ["img1.jpg"], ["img2.jpg"], ["img3.jpg"], ["img4.jpg"], ["img5.jpg"], ] gr.Examples( examples=example_images, inputs=[input_image], examples_per_page=5, ) detect_btn.click( fn=detect_disease, inputs=[input_image, leaf_seg_checkbox, confidence_slider], outputs=[output_image, detection_info] ) gr.HTML('') return demo if __name__ == "__main__": demo = create_demo() demo.launch()