4lph4v3rs3 commited on
Commit
3f6707a
·
verified ·
1 Parent(s): 44ae6c6

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +248 -0
  2. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import tensorflow as tf
3
+ import numpy as np
4
+ from PIL import Image
5
+ import os
6
+
7
+ # Define image dimensions
8
+ IMG_HEIGHT = 150
9
+ IMG_WIDTH = 150
10
+
11
+ # All 70 class names from the trained model
12
+ class_names = [
13
+ 'Algal Leaf Spot (Jackfruit)',
14
+ 'Anthracnose (Mango)',
15
+ 'Aphids (Cotton)',
16
+ 'Apple scab (Apple)',
17
+ 'Bacterial Blight (Cotton)',
18
+ 'Bacterial Canker (Mango)',
19
+ 'Bacterial Leaf Spot (Pumpkin)',
20
+ 'Bacterial spot (Peach)',
21
+ 'Bacterial spot (Pepper, bell)',
22
+ 'Bacterial spot (Tomato)',
23
+ 'BacterialBlights (Sugarcane)',
24
+ 'Black Rot (Cauliflower)',
25
+ 'Black Spot (Jackfruit)',
26
+ 'Black rot (Apple)',
27
+ 'Black rot (Grape)',
28
+ 'BrownSpot (Rice)',
29
+ 'Cedar apple rust (Apple)',
30
+ 'Cercospora leaf spot Gray leaf spot (Corn (maize))',
31
+ 'Common rust (Corn (maize))',
32
+ 'Cutting Weevil (Mango)',
33
+ 'Die Back (Mango)',
34
+ 'Downy Mildew (Pumpkin)',
35
+ 'Early blight (Potato)',
36
+ 'Early blight (Tomato)',
37
+ 'Esca (Black Measles) (Grape)',
38
+ 'Gall Midge (Mango)',
39
+ 'Haunglongbing (Citrus greening) (Orange)',
40
+ 'Healthy (Cauliflower)',
41
+ 'Healthy (Cotton)',
42
+ 'Healthy (Jackfruit)',
43
+ 'Healthy (Mango)',
44
+ 'Healthy (Rice)',
45
+ 'Healthy (Sugarcane)',
46
+ 'Healthy Leaf (Pumpkin)',
47
+ 'Hispa (Rice)',
48
+ 'Late blight (Potato)',
49
+ 'Late blight (Tomato)',
50
+ 'Leaf Mold (Tomato)',
51
+ 'Leaf blight (Isariopsis Leaf Spot) (Grape)',
52
+ 'Leaf scorch (Strawberry)',
53
+ 'LeafBlast (Rice)',
54
+ 'Mosaic (Sugarcane)',
55
+ 'Mosaic Disease (Pumpkin)',
56
+ 'Northern Leaf Blight (Corn (maize))',
57
+ 'Powdery Mildew (Cotton)',
58
+ 'Powdery Mildew (Mango)',
59
+ 'Powdery Mildew (Pumpkin)',
60
+ 'Powdery mildew (Cherry (including sour))',
61
+ 'RedRot (Sugarcane)',
62
+ 'Rust (Sugarcane)',
63
+ 'Septoria leaf spot (Tomato)',
64
+ 'Sooty Mould (Mango)',
65
+ 'Spider mites Two-spotted spider mite (Tomato)',
66
+ 'Target Spot (Tomato)',
67
+ 'Target spot (Cotton)',
68
+ 'Tomato Yellow Leaf Curl Virus (Tomato)',
69
+ 'Tomato mosaic virus (Tomato)',
70
+ 'Unknown Disease',
71
+ 'Yellow (Sugarcane)',
72
+ 'healthy (Apple)',
73
+ 'healthy (Blueberry)',
74
+ 'healthy (Cherry (including sour))',
75
+ 'healthy (Corn (maize))',
76
+ 'healthy (Grape)',
77
+ 'healthy (Peach)',
78
+ 'healthy (Pepper, bell)',
79
+ 'healthy (Potato)',
80
+ 'healthy (Raspberry)',
81
+ 'healthy (Soybean)',
82
+ 'healthy (Strawberry)',
83
+ 'healthy (Tomato)'
84
+ ]
85
+
86
+ # Load the TensorFlow SavedModel
87
+ print("Loading model...")
88
+ print(f"Current directory: {os.getcwd()}")
89
+ print(f"Files in current directory: {os.listdir('.')}")
90
+
91
+ model = None
92
+ infer = None
93
+
94
+ try:
95
+ # Try different possible model paths
96
+ possible_paths = [
97
+ './plant_disease_savemodel',
98
+ './plant_disease_savedmodel',
99
+ 'plant_disease_savemodel',
100
+ 'plant_disease_savedmodel'
101
+ ]
102
+
103
+ model_path = None
104
+ for path in possible_paths:
105
+ if os.path.exists(path):
106
+ model_path = path
107
+ print(f"Found model at: {model_path}")
108
+ break
109
+
110
+ if model_path is None:
111
+ raise FileNotFoundError("Model directory not found. Please ensure 'plant_disease_savemodel' folder is uploaded.")
112
+
113
+ # Check if model files exist
114
+ model_files = os.listdir(model_path)
115
+ print(f"Files in model directory: {model_files}")
116
+
117
+ # Load the model
118
+ model = tf.saved_model.load(model_path)
119
+ infer = model.signatures["serving_default"]
120
+ print(f"✅ Model loaded successfully from {model_path}")
121
+
122
+ except Exception as e:
123
+ print(f"❌ Error loading model: {e}")
124
+ import traceback
125
+ traceback.print_exc()
126
+ model = None
127
+ infer = None
128
+
129
+ def predict_disease(image):
130
+ """
131
+ Predict plant disease from an image
132
+
133
+ Args:
134
+ image: PIL Image or numpy array
135
+
136
+ Returns:
137
+ dict: Dictionary with class names as keys and confidence scores as values
138
+ Format compatible with CropGuard mobile app
139
+ """
140
+ if model is None or infer is None:
141
+ return {
142
+ "Error": 1.0,
143
+ "Message": "Model not loaded. Please check the model files."
144
+ }
145
+
146
+ try:
147
+ # Convert to PIL Image if needed
148
+ if isinstance(image, np.ndarray):
149
+ img = Image.fromarray(image.astype('uint8'), 'RGB')
150
+ else:
151
+ img = image
152
+
153
+ # Ensure RGB mode
154
+ if img.mode != 'RGB':
155
+ img = img.convert('RGB')
156
+
157
+ # Resize to model input size (150x150 as per training)
158
+ img = img.resize((IMG_WIDTH, IMG_HEIGHT))
159
+
160
+ # Convert to array and normalize
161
+ img_array = np.array(img, dtype=np.float32)
162
+ img_array = img_array / 255.0 # Normalize to [0, 1]
163
+
164
+ # Add batch dimension
165
+ img_array = np.expand_dims(img_array, axis=0)
166
+
167
+ # Make prediction
168
+ predictions = infer(tf.constant(img_array))
169
+
170
+ # Get the output tensor (try different possible keys)
171
+ if 'output_0' in predictions:
172
+ output = predictions['output_0'].numpy()
173
+ elif 'dense_1' in predictions:
174
+ output = predictions['dense_1'].numpy()
175
+ elif 'dense' in predictions:
176
+ output = predictions['dense'].numpy()
177
+ else:
178
+ # Use the first output
179
+ output = list(predictions.values())[0].numpy()
180
+
181
+ # Get predictions for all classes
182
+ predictions_dict = {}
183
+ for i, class_name in enumerate(class_names):
184
+ if i < len(output[0]):
185
+ predictions_dict[class_name] = float(output[0][i])
186
+
187
+ # Log top prediction for debugging
188
+ top_class = max(predictions_dict.items(), key=lambda x: x[1])
189
+ print(f"Top prediction: {top_class[0]} ({top_class[1]*100:.2f}%)")
190
+
191
+ # Return in format compatible with Gradio Label output
192
+ # Gradio will automatically show top predictions
193
+ # Mobile app expects: { "class_name": confidence, ... }
194
+ return predictions_dict
195
+
196
+ except Exception as e:
197
+ print(f"Prediction error: {str(e)}")
198
+ import traceback
199
+ traceback.print_exc()
200
+ return {
201
+ "Error": 1.0,
202
+ "Message": f"Prediction failed: {str(e)}"
203
+ }
204
+
205
+ # Create Gradio interface
206
+ title = "🌱 CropGuard Tech - Plant Disease Detection"
207
+ description = """
208
+ Upload an image of a plant leaf to detect diseases using AI.
209
+
210
+ **Supported Crops:** Apple, Blueberry, Cauliflower, Cherry, Corn, Cotton, Grape, Jackfruit, Mango, Orange, Peach, Pepper, Potato, Pumpkin, Raspberry, Rice, Soybean, Strawberry, Sugarcane, Tomato
211
+
212
+ **Model Specs:**
213
+ - 70 disease classes
214
+ - 95%+ accuracy
215
+ - CNN architecture
216
+ - Trained on 10,000+ images
217
+ """
218
+
219
+ article = """
220
+ ### About CropGuard Tech
221
+ This AI model was trained on Google Colab using a comprehensive plant disease dataset from Kaggle.
222
+ It can identify 70 different plant diseases across 19+ crop varieties.
223
+
224
+ **Creator:** Beauttah Kipruto (Student at Elimu High School)
225
+
226
+ **Model Repository:** [View on Hugging Face](https://huggingface.co/4lph4v3rs3/plant-disease-classification-model)
227
+ """
228
+
229
+ examples = [
230
+ # You can add example images here if you have them
231
+ ]
232
+
233
+ # Create the interface
234
+ iface = gr.Interface(
235
+ fn=predict_disease,
236
+ inputs=gr.Image(type="pil", label="Upload Plant Leaf Image"),
237
+ outputs=gr.Label(num_top_classes=5, label="Disease Predictions"),
238
+ title=title,
239
+ description=description,
240
+ article=article,
241
+ examples=examples,
242
+ theme=gr.themes.Soft(),
243
+ allow_flagging="never"
244
+ )
245
+
246
+ # Launch the app
247
+ if __name__ == "__main__":
248
+ iface.launch()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ tensorflow-cpu==2.13.0
2
+ gradio==4.16.0
3
+ numpy==1.24.3
4
+ Pillow==10.2.0