abdullahzunorain's picture
Create app.py
e9ead59 verified
import streamlit as st
from PIL import Image
import torch
from transformers import AutoModelForImageClassification, AutoFeatureExtractor
from groq import Groq
from dotenv import load_dotenv
import os
# Load environment variables from the .env file
load_dotenv()
# Securely get the GROQ API key from environment variables
groq_api_key = os.getenv("GROQ_API_KEY")
if not groq_api_key:
raise ValueError("GROQ_API_KEY environment variable not set.")
# Initialize the client with the API key
client = Groq(api_key=groq_api_key)
# Expanded dictionary with treatments for various diseases
disease_treatments = {
"Grape with Black Rot": "Prune affected areas, avoid water on leaves, use fungicide if severe.",
"Potato with Early Blight": "Apply fungicides, avoid overhead watering, rotate crops yearly.",
"Tomato with Early Blight": "Remove infected leaves, use copper-based fungicide, maintain good airflow.",
"Apple with Scab": "Remove fallen leaves, prune trees, apply fungicide in early spring.",
"Wheat with Leaf Rust": "Apply resistant varieties, use fungicides, remove weeds.",
"Cucumber with Downy Mildew": "Use resistant varieties, ensure good air circulation, apply fungicide.",
"Rose with Powdery Mildew": "Use sulfur or potassium bicarbonate sprays, prune affected areas, avoid overhead watering.",
"Strawberry with Gray Mold": "Remove infected fruits, improve ventilation, avoid wetting the fruit when watering.",
"Peach with Leaf Curl": "Apply a fungicide in late fall or early spring, remove affected leaves.",
"Banana with Panama Disease": "Use disease-resistant varieties, ensure soil drainage, avoid overwatering.",
"Tomato with Septoria Leaf Spot": "Use resistant varieties, remove infected leaves, apply fungicide.",
"Corn with Smut": "Remove infected ears, use disease-free seed, rotate crops.",
"Carrot with Root Rot": "Ensure well-draining soil, avoid excessive watering, use crop rotation.",
"Onion with Downy Mildew": "Use fungicides, ensure adequate spacing, avoid overhead watering.",
"Potato with Late Blight": "Apply copper-based fungicides, remove affected foliage, practice crop rotation.",
"Citrus with Greening Disease": "Remove infected trees, control leafhopper population, plant disease-free trees.",
"Lettuce with Downy Mildew": "Ensure good air circulation, avoid overhead watering, apply fungicides.",
"Pepper with Bacterial Spot": "Use resistant varieties, apply copper-based bactericides, practice crop rotation.",
"Eggplant with Verticillium Wilt": "Use resistant varieties, solarize soil before planting, avoid soil disturbance.",
"Cotton with Boll Rot": "Improve drainage, remove infected bolls, apply fungicides if necessary.",
"Soybean with Soybean Rust": "Use fungicides, rotate crops, use resistant varieties if available.",
"Rice with Sheath Blight": "Reduce nitrogen application, maintain proper water levels, apply fungicides.",
"Sunflower with Downy Mildew": "Use resistant varieties, avoid waterlogging, apply fungicides.",
"Barley with Net Blotch": "Use resistant varieties, remove crop residues, apply fungicides.",
"Oat with Crown Rust": "Use resistant varieties, apply fungicides, avoid high nitrogen levels.",
"Sugarcane with Red Rot": "Use disease-free cuttings, control weeds, apply fungicides if necessary.",
"Pine with Pine Wilt": "Remove and destroy infected trees, control beetle population, avoid planting susceptible species.",
"Avocado with Anthracnose": "Prune infected branches, use copper-based fungicides, avoid wet foliage.",
"Papaya with Papaya Ringspot Virus": "Use virus-resistant varieties, remove infected plants, control aphid population.",
"Mango with Powdery Mildew": "Use sulfur-based fungicides, remove affected parts, avoid overhead watering.",
"Peanut with Leaf Spot": "Use resistant varieties, apply fungicides, rotate crops to reduce infection risk.",
"Chili with Anthracnose": "Apply copper fungicides, remove infected fruits, avoid overhead irrigation.",
"Garlic with White Rot": "Remove infected plants, improve soil drainage, practice crop rotation."
}
# Streamlit title and description
st.title("🌿 Plant Disease Detection 🌿")
st.write("Upload an image of a plant leaf, and the app will detect the disease and suggest a treatment.")
# File upload option
uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png", "bmp", "gif", "tiff", "webp"])
if uploaded_file is not None:
# Open the image using PIL and display it
image = Image.open(uploaded_file)
image = image.convert("RGB")
st.image(image, caption="Uploaded Image", use_container_width=True)
# Initialize the feature extractor and model
extractor = AutoFeatureExtractor.from_pretrained("linkanjarad/mobilenet_v2_1.0_224-plant-disease-identification")
model = AutoModelForImageClassification.from_pretrained("linkanjarad/mobilenet_v2_1.0_224-plant-disease-identification")
# Preprocess the image
inputs = extractor(images=image, return_tensors="pt")
# Get the model's raw prediction (logits)
outputs = model(**inputs)
logits = outputs.logits
# Temperature scaling for logits (lowering temperature to adjust confidence)
temperature = 0.5
logits = logits / temperature
# Convert logits to probabilities using softmax
softmax = torch.nn.Softmax(dim=1)
probabilities = softmax(logits)
# Get the top prediction
top_k = 1
top_probs, top_indices = torch.topk(probabilities, top_k, dim=1)
top_probs = top_probs[0].tolist()
top_indices = top_indices[0].tolist()
# Define a confidence threshold
confidence_threshold = 0.7
class_labels = model.config.id2label
predicted_disease = "Unknown Disease"
predicted_confidence = top_probs[0]
# Handle low-confidence predictions
if predicted_confidence >= confidence_threshold:
predicted_disease = class_labels.get(top_indices[0], "Unknown Disease")
else:
predicted_disease = "Unknown Disease"
st.warning("The model could not confidently identify a disease. Please try again with a clearer image.")
# Fetch treatment from the dictionary
treatment = disease_treatments.get(predicted_disease, "No treatment information available.")
# Display prediction and treatment
st.write(f"**Predicted Disease:** {predicted_disease}")
st.write(f"**Confidence Level:** {predicted_confidence:.2f}")
# Generate detailed report (using prompts)
symptoms = "leaf discoloration, spots, mold, wilting" # This can be dynamically generated based on the image features
diagnosis_prompt = f"Identify the disease or pest affecting a plant with the following symptoms: {symptoms}."
treatment_prompt = f"Suggest treatments for a plant disease with symptoms like {symptoms}. Include organic and chemical treatment options if available."
preventive_prompt = f"Provide preventive measures for plant diseases with symptoms similar to {symptoms}."
# Combine the prompts into the chat context
chat_context = f"""
### 🌱 Plant Disease Diagnosis Report 🌱
#### 🌟 Predicted Disease
- **Disease**: {predicted_disease}
- **Confidence Level**: {predicted_confidence:.2f}
#### πŸ“ Disease Diagnosis and Symptoms
- **Diagnosis**: {diagnosis_prompt}
#### πŸ’Š Treatment Recommendations
- **Treatment**: {treatment_prompt}
#### πŸ›‘οΈ Preventive Measures
- **Prevention**: {preventive_prompt}
#### πŸ”š Conclusion
- **Next Steps**: Consult a local expert for further advice.
"""
# Generate report using Groq (or any other service)
try:
chat_completion = client.chat.completions.create(
messages=[
{
"role": "system",
"content": (
"You are a plant disease analysis assistant. Your task is to provide a comprehensive, actionable diagnosis report."
"The report should include the predicted disease, its symptoms, recommended treatments, and prevention tips. "
"Ensure the report is actionable and easy to understand for non-experts in agriculture."
)
},
{
"role": "user",
"content": chat_context
}
],
model="mixtral-8x7b-32768", # Adjust this to the model you're using
temperature=0.7, # Adjust to balance creativity and precision
max_tokens=5000 # Limit to ensure the output is not cut off
)
# Display the generated report in the Streamlit app
st.markdown("---")
# Display the full HTML report generated by Groq
st.markdown(chat_completion.choices[0].message.content, unsafe_allow_html=True)
except Exception as e:
# If there's an error with the Groq API call, display an error message
st.error(f"Error generating report: {str(e)}")