File size: 5,727 Bytes
36ef4a7
 
 
 
9281224
e65618e
36ef4a7
9281224
36ef4a7
9281224
 
 
 
 
 
 
 
 
 
e65618e
9281224
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36ef4a7
e65618e
 
36ef4a7
 
 
 
9281224
 
 
36ef4a7
 
 
 
 
 
9281224
 
 
 
 
36ef4a7
 
 
 
 
 
 
 
 
9281224
36ef4a7
 
 
 
9281224
 
 
e65618e
 
 
 
 
 
 
 
 
 
36ef4a7
 
 
9281224
36ef4a7
9281224
 
 
36ef4a7
 
 
 
e65618e
36ef4a7
 
 
 
 
e65618e
36ef4a7
 
9281224
e65618e
9281224
e65618e
 
36ef4a7
 
 
 
e65618e
 
 
36ef4a7
 
 
 
e65618e
 
 
36ef4a7
 
 
e65618e
36ef4a7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9281224
36ef4a7
 
 
 
 
 
 
 
 
9281224
 
36ef4a7
 
 
 
 
 
 
 
 
 
 
 
 
 
9281224
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import gradio as gr
from ultralytics import YOLO
import cv2
import numpy as np
from PIL import Image
import os

# Load the model with proper error handling
def load_model():
    model_paths = [
        'best_model.pt',
        'tree_disease_detector.pt',
        './best_model.pt',
        './tree_disease_detector.pt'
    ]
    
    # Try to load from local files first
    for path in model_paths:
        if os.path.exists(path):
            try:
                print(f"Loading model from {path}")
                model = YOLO(path)
                return model, f"Tree Disease Detection Model ({path})"
            except Exception as e:
                print(f"Error loading {path}: {e}")
                continue
    
    # Fallback to standard YOLOv8s
    try:
        print("Loading standard YOLOv8s model...")
        model = YOLO('yolov8s.pt')
        return model, "Standard YOLOv8s Model (Fallback)"
    except Exception as e:
        print(f"Error loading YOLOv8s: {e}")
        return None, "No model available"

# Load model and get status
model, model_status = load_model()

def detect_tree_disease(image, conf_threshold=0.25, iou_threshold=0.45):
    """Detect unhealthy trees in the uploaded image"""
    
    if model is None:
        return image, "Error: No model available"
    
    # Convert PIL image to numpy array
    image_np = np.array(image)
    
    # Run inference
    results = model(image_np, conf=conf_threshold, iou=iou_threshold)
    
    # Get annotated image directly from results
    annotated_img = results[0].plot()
    annotated_img = cv2.cvtColor(annotated_img, cv2.COLOR_BGR2RGB)
    annotated_img = Image.fromarray(annotated_img)
    
    # Extract detections
    detections = []
    for result in results:
        boxes = result.boxes
        if boxes is not None:
            for box in boxes:
                detection = {
                    'confidence': float(box.conf[0]),
                    'bbox': box.xyxy[0].tolist(),
                    'class': 'unhealthy'
                }
                detections.append(detection)
    
    # Create detection summary
    is_custom_model = "Tree Disease Detection Model" in model_status
    
    if is_custom_model:
        summary = f"Detected {len(detections)} unhealthy tree(s)\n\n"
        for i, det in enumerate(detections, 1):
            summary += f"Tree {i}: Confidence {det['confidence']:.2f}\n"
    else:
        summary = f"Using {model_status}\n"
        summary += f"Detected {len(detections)} object(s)\n\n"
        for i, det in enumerate(detections, 1):
            summary += f"Object {i}: Confidence {det['confidence']:.2f}\n"
    
    summary += f"\nModel Status: {model_status}"
    
    return annotated_img, summary

# Create example images (tree images)
example_images = [
    ["https://images.pexels.com/photos/1632790/pexels-photo-1632790.jpeg", 0.25, 0.45],
    ["https://images.pexels.com/photos/38537/woodland-road-falling-leaf-natural-38537.jpeg", 0.25, 0.45],
    ["https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/Ash_Tree_-_geograph.org.uk_-_590710.jpg/640px-Ash_Tree_-_geograph.org.uk_-_590710.jpg", 0.25, 0.45],
]

# Create Gradio interface
with gr.Blocks(title="Tree Disease Detection") as demo:
    gr.Markdown(f"""
    # 🌳 Tree Disease Detection with YOLOv8
    
    This model detects unhealthy/diseased trees in aerial UAV imagery. 
    Upload an image or use one of the examples below to detect diseased trees.
    
    **Current Model**: {model_status}
    """)
    
    if "Fallback" in model_status:
        gr.Markdown("""
        ⚠️ **Note**: Using a fallback model. Detection will work but won't be specific to tree diseases.
        """)
    
    with gr.Row():
        with gr.Column():
            input_image = gr.Image(type="pil", label="Upload Image")
            conf_threshold = gr.Slider(
                minimum=0.0,
                maximum=1.0,
                value=0.25,
                step=0.05,
                label="Confidence Threshold"
            )
            iou_threshold = gr.Slider(
                minimum=0.0,
                maximum=1.0,
                value=0.45,
                step=0.05,
                label="IoU Threshold"
            )
            detect_button = gr.Button("Detect Tree Disease", variant="primary")
        
        with gr.Column():
            output_image = gr.Image(type="pil", label="Detection Results")
            detection_summary = gr.Textbox(label="Detection Summary", lines=10)
    
    # Set up event handler
    detect_button.click(
        fn=detect_tree_disease,
        inputs=[input_image, conf_threshold, iou_threshold],
        outputs=[output_image, detection_summary]
    )
    
    # Add examples
    gr.Examples(
        examples=example_images,
        inputs=[input_image, conf_threshold, iou_threshold],
        outputs=[output_image, detection_summary],
        fn=detect_tree_disease,
        cache_examples=False,
    )
    
    gr.Markdown("""
    ## About this Model
    
    - **Architecture**: YOLOv8s
    - **Dataset**: [PDT Dataset](https://huggingface.co/datasets/qwer0213/PDT_dataset)
    - **mAP50**: 0.933
    - **mAP50-95**: 0.659
    - **Precision**: 0.878
    - **Recall**: 0.863
    - **Classes**: 1 (unhealthy trees)
    
    ## Usage Tips
    
    - This model works best with aerial/UAV imagery
    - Optimal input resolution: 640x640 pixels
    - Adjust confidence threshold to filter detections
    - Lower IoU threshold for overlapping trees
    
    [Model Card](https://huggingface.co/IsmatS/crop_desease_detection) | 
    [Dataset](https://huggingface.co/datasets/qwer0213/PDT_dataset)
    """)

# Launch the app
if __name__ == "__main__":
    demo.launch()