devmalik-official commited on
Commit
07dd47d
·
verified ·
1 Parent(s): 84cf127

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +185 -0
  2. requirements.txt +0 -0
app.py ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ from transformers import AutoImageProcessor, SiglipForImageClassification, pipeline
4
+ from torchvision import transforms
5
+ from PIL import Image
6
+ import numpy as np
7
+ import os
8
+
9
+ # -------------------------------
10
+ # Model paths (local folders)
11
+ # -------------------------------
12
+ hf_model_names = {
13
+ "Rice": "models/Rice-Leaf-Disease",
14
+ "Sugarcane": "models/sugarcane-plant-diseases-classification",
15
+ "Tomato": "models/tomato-leaf-disease-classification-resnet50",
16
+ "Corn/Wheat": "models/crop_leaf_diseases_vit"
17
+ }
18
+
19
+ # -------------------------------
20
+ # Utility: Load model offline or online
21
+ # -------------------------------
22
+ def load_model_or_fallback(model_name, model_path, use_pipeline=False, skip_processor=False):
23
+ if os.path.exists(model_path):
24
+ print(f"✅ Loading local model: {model_path}")
25
+ if use_pipeline:
26
+ return pipeline("image-classification", model=model_path)
27
+ elif skip_processor:
28
+ model = SiglipForImageClassification.from_pretrained(model_path)
29
+ return None, model
30
+ else:
31
+ processor = AutoImageProcessor.from_pretrained(model_path)
32
+ model = SiglipForImageClassification.from_pretrained(model_path)
33
+ return processor, model
34
+ else:
35
+ print(f"🌐 Model not found locally. Fetching from Hugging Face Hub: {model_name}")
36
+ if use_pipeline:
37
+ return pipeline("image-classification", model=model_name)
38
+ elif skip_processor:
39
+ model = SiglipForImageClassification.from_pretrained(model_name)
40
+ return None, model
41
+ else:
42
+ processor = AutoImageProcessor.from_pretrained(model_name)
43
+ model = SiglipForImageClassification.from_pretrained(model_name)
44
+ return processor, model
45
+
46
+ # -------------------------------
47
+ # Load models
48
+ # -------------------------------
49
+ hf_processors = {}
50
+ hf_models = {}
51
+
52
+ # Rice
53
+ hf_processors['Rice'], hf_models['Rice'] = load_model_or_fallback(
54
+ "prithivMLmods/Rice-Leaf-Disease", hf_model_names["Rice"]
55
+ )
56
+ # Sugarcane (skip processor)
57
+ _, hf_models['Sugarcane'] = load_model_or_fallback(
58
+ "dwililiya/sugarcane-plant-diseases-classification",
59
+ hf_model_names["Sugarcane"],
60
+ skip_processor=True
61
+ )
62
+ # Tomato (pipeline)
63
+ hf_models['Tomato'] = load_model_or_fallback(
64
+ "wellCh4n/tomato-leaf-disease-classification-resnet50",
65
+ hf_model_names["Tomato"], use_pipeline=True
66
+ )
67
+ # Corn/Wheat (pipeline)
68
+ hf_models['Corn/Wheat'] = load_model_or_fallback(
69
+ "wambugu71/crop_leaf_diseases_vit",
70
+ hf_model_names["Corn/Wheat"], use_pipeline=True
71
+ )
72
+
73
+ # -------------------------------
74
+ # Sugarcane manual preprocessing
75
+ # -------------------------------
76
+ sugarcane_transform = transforms.Compose([
77
+ transforms.Resize((224, 224)),
78
+ transforms.ToTensor(),
79
+ transforms.Normalize(mean=[0.485, 0.456, 0.406],
80
+ std=[0.229, 0.224, 0.225])
81
+ ])
82
+
83
+ # -------------------------------
84
+ # Disease mapping
85
+ # -------------------------------
86
+ disease_dict = {
87
+ "Rice": ["Bacterial Blight", "Blast", "Brown Spot", "Healthy", "Tungro"],
88
+ "Sugarcane": ["Bacterial Blight", "Healthy", "Mosaic", "Red Rot", "Rust", "Yellow"],
89
+ "Tomato": ["Early Blight", "Late Blight", "Healthy"],
90
+ "Corn/Wheat": ["Healthy", "Rust", "Blight", "Leaf Spot"] # Adjust based on your model labels
91
+ }
92
+
93
+ # Remedies mapping
94
+ remedies = {
95
+ "Early Blight": "Remove infected leaves, apply fungicide.",
96
+ "Late Blight": "Use fungicides and remove infected plants.",
97
+ "Bacterial Blight": "Use resistant varieties and avoid overhead watering.",
98
+ "Blast": "Use balanced fertilizer, apply fungicide.",
99
+ "Brown Spot": "Ensure proper field drainage and avoid overcrowding.",
100
+ "Tungro": "Control green leafhoppers and remove infected plants.",
101
+ "Mosaic": "Remove infected plants, avoid spread.",
102
+ "Red Rot": "Remove infected plants, apply fungicide.",
103
+ "Rust": "Use fungicide and resistant varieties.",
104
+ "Yellow": "Monitor plant, apply preventive measures.",
105
+ "Leaf Spot": "Remove affected leaves and apply fungicide.",
106
+ "Blight": "Use disease-free seeds and apply fungicides.",
107
+ "Healthy": "No action needed."
108
+ }
109
+
110
+ # -------------------------------
111
+ # Prediction function
112
+ # -------------------------------
113
+ def predict_disease(crop, img):
114
+ if img is None:
115
+ return "No image uploaded", "Please upload a leaf image."
116
+
117
+ img_pil = Image.fromarray(img).convert("RGB")
118
+
119
+ if crop == "Rice":
120
+ inputs = hf_processors[crop](images=img_pil, return_tensors="pt")
121
+ with torch.no_grad():
122
+ outputs = hf_models[crop](**inputs)
123
+ logits = outputs.logits
124
+ probs = torch.nn.functional.softmax(logits, dim=1).squeeze().tolist()
125
+ predicted_idx = int(np.argmax(probs))
126
+ disease = disease_dict[crop][predicted_idx]
127
+ advice = remedies.get(disease, "No advice available.")
128
+ return disease, advice
129
+
130
+ elif crop == "Sugarcane":
131
+ img_tensor = sugarcane_transform(img_pil).unsqueeze(0)
132
+ with torch.no_grad():
133
+ outputs = hf_models[crop](img_tensor)
134
+ logits = outputs.logits
135
+ probs = torch.nn.functional.softmax(logits, dim=1).squeeze().tolist()
136
+ predicted_idx = int(np.argmax(probs))
137
+ disease = disease_dict[crop][predicted_idx]
138
+ advice = remedies.get(disease, "No advice available.")
139
+ return disease, advice
140
+
141
+ elif crop in ["Tomato", "Corn/Wheat"]:
142
+ result = hf_models[crop](img_pil)[0]
143
+ disease = result['label']
144
+ advice = remedies.get(disease, "No advice available.")
145
+ return disease, advice
146
+
147
+ else:
148
+ return "Error", f"Model for {crop} is not available."
149
+
150
+ # -------------------------------
151
+ # Gradio Interface
152
+ # -------------------------------
153
+ custom_css = """
154
+ body, .gradio-container {
155
+ background-image: url('https://media.istockphoto.com/id/1328004520/photo/healthy-young-soybean-crop-in-field-at-dawn.jpg?s=612x612&w=0&k=20&c=XRw20PArfhkh6LLgFrgvycPLm0Uy9y7lu9U7fLqabVY=');
156
+ background-size: cover;
157
+ background-repeat: no-repeat;
158
+ background-attachment: fixed;
159
+ min-height: 100vh !important;
160
+ }
161
+ .gradio-container > * {
162
+ background-color: rgba(255, 255, 255, 0.88) !important;
163
+ border-radius: 15px;
164
+ padding: 20px;
165
+ }
166
+ """
167
+
168
+ with gr.Blocks(css=custom_css) as app:
169
+ gr.Markdown("## 🌿 Crop Disease Detector")
170
+ gr.Markdown("Upload a leaf image of your crop and get AI-based disease prediction with remedies.")
171
+
172
+ with gr.Row():
173
+ with gr.Column():
174
+ crop_input = gr.Dropdown(list(hf_model_names.keys()), label="Select Crop")
175
+ img_input = gr.Image(type="numpy", label="Upload Leaf Image")
176
+ predict_btn = gr.Button("🔍 Predict Disease")
177
+
178
+ with gr.Column():
179
+ disease_output = gr.Textbox(label="Predicted Disease")
180
+ advice_output = gr.Textbox(label="Recommended Action")
181
+
182
+ predict_btn.click(predict_disease, inputs=[crop_input, img_input], outputs=[disease_output, advice_output])
183
+
184
+ # Launch
185
+ app.launch(server_name="127.0.0.1", server_port=7860, share=True)
requirements.txt ADDED
Binary file (4.96 kB). View file