Spaces:
Sleeping
Sleeping
import gradio as gr | |
from PIL import Image | |
import numpy as np | |
import onnxruntime as ort | |
import os | |
from dotenv import load_dotenv | |
import ast | |
from openai import OpenAI | |
# Load environment variables | |
load_dotenv() | |
# === Load and clean class names === | |
class_file_path = "class_names.txt" | |
with open(class_file_path, "r") as f: | |
raw_line = f.read() | |
class_names = ast.literal_eval(raw_line.replace("Classes: ", "").strip()) | |
# === Load ONNX model === | |
model_path = "model.onnx" | |
learn = ort.InferenceSession(model_path) | |
# === OpenRouter setup === | |
client = OpenAI( | |
base_url="https://openrouter.ai/api/v1", | |
api_key=os.getenv("OPENROUTER_API_KEY"), | |
) | |
def generate_description_and_prevention(label): | |
if label == "not_a_crop": | |
return ( | |
"The uploaded image does not seem to show a valid crop or leaf.", | |
"Please upload a clear image of a single crop or a leaf showing disease symptoms." | |
) | |
prompt = ( | |
f"Explain in simple words what the plant disease or condition '{label}' is, " | |
f"and give 2 to 4 clear, practical prevention tips.\n" | |
"Use this format:\n" | |
"Description:\n" | |
"Explain briefly what this disease is and how it affects the plant.\n" | |
"Prevention:\n" | |
"- Tip 1\n" | |
"- Tip 2\n" | |
"- (Optional) Tip 3\n" | |
"- (Optional) Tip 4" | |
) | |
try: | |
response = client.chat.completions.create( | |
model="deepseek/deepseek-r1:free", | |
messages=[ | |
{"role": "system", "content": "You are a knowledgeable plant pathologist."}, | |
{"role": "user", "content": prompt} | |
], | |
temperature=0.7, | |
max_tokens=800 | |
) | |
content = response.choices[0].message.content | |
if "Description:" in content and "Prevention:" in content: | |
parts = content.split("Prevention:") | |
description = parts[0].replace("Description:", "").strip() | |
prevention = parts[1].strip() | |
return description, prevention | |
else: | |
return "Description not structured correctly.", "No prevention steps found." | |
except Exception as e: | |
print(f"[ERROR] OpenRouter API error: {e}") | |
return "OpenRouter error.", "Failed to generate prevention steps." | |
def preprocess_image(image, size=(224, 224)): | |
image = image.resize(size) | |
img_array = np.array(image).astype(np.float32) / 255.0 | |
img_array = img_array.transpose(2, 0, 1) | |
img_array = np.expand_dims(img_array, axis=0) | |
return img_array | |
def predict(image): | |
image = image.convert("RGB") | |
input_tensor = preprocess_image(image) | |
input_name = learn.get_inputs()[0].name | |
outputs = learn.run(None, {input_name: input_tensor}) | |
probs = outputs[0][0] | |
pred_idx = int(np.argmax(probs)) | |
pred_class = class_names[pred_idx] | |
confidence = float(probs[pred_idx] * 100) | |
description, prevention = generate_description_and_prevention(pred_class) | |
return pred_class, round(confidence, 2), description, prevention | |
# === Gradio Interface === | |
iface = gr.Interface( | |
fn=predict, | |
inputs=gr.Image(type="pil"), | |
outputs=[ | |
gr.Label(label="Prediction"), | |
gr.Number(label="Confidence %"), | |
gr.Textbox(label="Description"), | |
gr.Textbox(label="Prevention") | |
], | |
title="🌱 Crop Disease Detection", | |
description="Upload a crop or leaf image to detect plant diseases and get prevention tips." | |
) | |
if __name__ == "__main__": | |
iface.launch(server_name="0.0.0.0", server_port=7860, debug=True) |