MaryPazRB commited on
Commit
ee102b7
·
1 Parent(s): 60826fb

first working version

Browse files
Files changed (4) hide show
  1. .gradio/certificate.pem +31 -0
  2. app.py +191 -7
  3. clr_YOLOV8.pt +3 -0
  4. requirements.txt +10 -1
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
app.py CHANGED
@@ -1,13 +1,197 @@
 
 
1
  import gradio as gr
 
 
 
 
2
 
3
- def hello(image):
4
- return "Coffee rust analysis coming soon!"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  demo = gr.Interface(
7
- fn=hello,
8
- inputs=gr.Image(),
9
- outputs="text",
10
- title="Coffee Leaf Rust Severity Estimator"
 
 
 
 
 
 
 
11
  )
12
 
13
- demo.launch()
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
  import gradio as gr
4
+ import numpy as np
5
+ from PIL import Image
6
+ import torch
7
+ from ultralytics import YOLO
8
 
9
+ ############################################
10
+ # Configuration
11
+ ############################################
12
+
13
+ YOLO_MODEL_PATH = "clr_YOLOV8.pt"
14
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
15
+
16
+ ############################################
17
+ # Load YOLO Model
18
+ ############################################
19
+
20
+ print("Loading YOLO model...")
21
+
22
+ try:
23
+ yolo_model = YOLO(YOLO_MODEL_PATH)
24
+ print("YOLO model loaded.")
25
+ except Exception as e:
26
+ yolo_model = None
27
+ print("YOLO loading error:", e)
28
+
29
+ ############################################
30
+ # Helper Functions
31
+ ############################################
32
+
33
+ def segment_rust_simple(leaf_img):
34
+ """
35
+ Simple rust segmentation using HSV color threshold.
36
+ Works as fallback when SAM is unavailable.
37
+ """
38
+
39
+ hsv = cv2.cvtColor(leaf_img, cv2.COLOR_BGR2HSV)
40
+
41
+ # Rust-like colors
42
+ lower = np.array([10, 80, 80])
43
+ upper = np.array([35, 255, 255])
44
+
45
+ mask = cv2.inRange(hsv, lower, upper)
46
+
47
+ kernel = np.ones((3,3), np.uint8)
48
+ mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
49
+
50
+ return mask
51
+
52
+
53
+ def calculate_leaf_area(leaf_img):
54
+ """
55
+ Estimate leaf pixels via threshold.
56
+ """
57
+ gray = cv2.cvtColor(leaf_img, cv2.COLOR_BGR2GRAY)
58
+ _, mask = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
59
+
60
+ return mask
61
+
62
+
63
+ ############################################
64
+ # Main Processing Function
65
+ ############################################
66
+
67
+ def process_coffee_leaf(image):
68
+
69
+ if image is None:
70
+ return None, "Upload an image."
71
+
72
+ if yolo_model is None:
73
+ return image, "YOLO model not loaded."
74
+
75
+ image_np = np.array(image)
76
+ image_cv = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
77
+
78
+ results = yolo_model(image_cv, verbose=False)
79
+
80
+ boxes = results[0].boxes.xyxy.cpu().numpy()
81
+
82
+ if len(boxes) == 0:
83
+ return image_np, "No leaves detected."
84
+
85
+ annotated = image_np.copy()
86
+
87
+ severities = []
88
+
89
+ h, w = image_cv.shape[:2]
90
+
91
+ for i, box in enumerate(boxes):
92
+
93
+ x1, y1, x2, y2 = box.astype(int)
94
+
95
+ x1, x2 = max(0, x1), min(w, x2)
96
+ y1, y2 = max(0, y1), min(h, y2)
97
+
98
+ leaf_crop = image_cv[y1:y2, x1:x2]
99
+
100
+ if leaf_crop.size == 0:
101
+ continue
102
+
103
+ ################################
104
+ # Leaf mask
105
+ ################################
106
+
107
+ leaf_mask = calculate_leaf_area(leaf_crop)
108
+ leaf_pixels = cv2.countNonZero(leaf_mask)
109
+
110
+ ################################
111
+ # Rust segmentation
112
+ ################################
113
+
114
+ rust_mask = segment_rust_simple(leaf_crop)
115
+ rust_pixels = cv2.countNonZero(rust_mask)
116
+
117
+ ################################
118
+ # Severity calculation
119
+ ################################
120
+
121
+ severity = 0
122
+
123
+ if leaf_pixels > 0:
124
+ severity = (rust_pixels / leaf_pixels) * 100
125
+
126
+ severities.append(f"Leaf {i+1}: {severity:.2f}%")
127
+
128
+ ################################
129
+ # Visualization
130
+ ################################
131
+
132
+ # draw leaf bbox
133
+ cv2.rectangle(annotated,(x1,y1),(x2,y2),(0,255,0),2)
134
+
135
+ cv2.putText(
136
+ annotated,
137
+ f"{severity:.1f}%",
138
+ (x1,y1-5),
139
+ cv2.FONT_HERSHEY_SIMPLEX,
140
+ 0.6,
141
+ (0,255,0),
142
+ 2
143
+ )
144
+
145
+ # resize rust mask to image coords
146
+ rust_mask = cv2.resize(
147
+ rust_mask,
148
+ (x2-x1, y2-y1),
149
+ interpolation=cv2.INTER_NEAREST
150
+ )
151
+
152
+ overlay = np.zeros_like(annotated)
153
+
154
+ overlay[y1:y2, x1:x2][rust_mask > 0] = [255,0,0]
155
+
156
+ alpha = 0.4
157
+ mask_indices = overlay[:,:,0] > 0
158
+
159
+ annotated[mask_indices] = (
160
+ annotated[mask_indices]*(1-alpha) +
161
+ overlay[mask_indices]*alpha
162
+ ).astype(np.uint8)
163
+
164
+ report = f"Detected {len(boxes)} leaves\n\n"
165
+ report += "\n".join(severities)
166
+
167
+ return annotated, report
168
+
169
+
170
+ ############################################
171
+ # Gradio Interface
172
+ ############################################
173
 
174
  demo = gr.Interface(
175
+ fn=process_coffee_leaf,
176
+ inputs=gr.Image(type="pil", label="Upload Coffee Leaf Image"),
177
+ outputs=[
178
+ gr.Image(label="Analyzed Image"),
179
+ gr.Textbox(label="Severity Report")
180
+ ],
181
+ title="☕ Coffee Leaf Rust Severity Estimator",
182
+ description="""
183
+ Upload a coffee leaf image.
184
+ The system detects leaves using YOLOv8 and estimates rust severity by segmenting rust-colored lesions.
185
+ """,
186
  )
187
 
188
+
189
+ ############################################
190
+ # Launch
191
+ ############################################
192
+
193
+ if __name__ == "__main__":
194
+ demo.launch(
195
+ server_name="0.0.0.0",
196
+ server_port=7860
197
+ )
clr_YOLOV8.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2480dc0328856e904fabe1f695b7b583dfbf601eb91f54c0c2566237d7a515c9
3
+ size 6758388
requirements.txt CHANGED
@@ -1 +1,10 @@
1
- gradio
 
 
 
 
 
 
 
 
 
 
1
+ gradio
2
+ ultralytics
3
+ torch
4
+ torchvision
5
+ numpy
6
+ opencv-python
7
+ pandas
8
+ Pillow
9
+ huggingface_hub
10
+ sam3