import gradio as gr
import pandas as pd
import lightgbm as lgb
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from google.generativeai import GenerativeModel, configure
from gtts import gTTS
import speech_recognition as sr
import os
import tempfile
import torch
from torchvision import models, transforms
from PIL import Image
import json
# from langdetect import detect
# ---------------------------
# Gemini Configuration
# ---------------------------
GOOGLE_API_KEY = "AIzaSyADMlXoD7OGN_yg6QZJvomb0mdK9nT6xE4" # Replace with your API key in double quotes
configure(api_key=GOOGLE_API_KEY)
gemini_model = GenerativeModel("models/gemini-1.5-flash")
# ---------------------------
# Crop Recommendation Setup
# ---------------------------
url = "https://raw.githubusercontent.com/sehajpreet22/data/refs/heads/main/cleaned_crop_data_with_pbi_labels.csv"
data = pd.read_csv(url)
X = data.drop('label', axis=1)
y = data['label']
le = LabelEncoder()
y_encoded = le.fit_transform(y)
X_train, X_test, y_train, y_test = train_test_split(X, y_encoded, test_size=0.3, random_state=0)
model = lgb.LGBMClassifier()
model.fit(X_train, y_train)
def predict_crop(ਨਾਈਟ੍ਰੋਜਨ, ਫਾਸਫੋਰਸ, ਪੋਟਾਸ਼ੀਅਮ, ਤਾਪਮਾਨ, ਨਮੀ, ਮਿੱਟੀ_pH, ਵਰਖਾ):
input_data = np.array([[ਨਾਈਟ੍ਰੋਜਨ, ਫਾਸਫੋਰਸ, ਪੋਟਾਸ਼ੀਅਮ, ਤਾਪਮਾਨ, ਨਮੀ, ਮਿੱਟੀ_pH, ਵਰਖਾ]])
pred = model.predict(input_data)[0]
crop_name = le.inverse_transform([pred])[0]
image_path = f"crop_images/{crop_name}.jpeg"
if not os.path.exists(image_path):
image_path = None
return image_path, f"🌾ਤੁਹਾਡੇ ਖੇਤ ਲਈ ਸੁਝਾਈ ਗਈ ਫਸਲ: *{crop_name}*"
# ---------------------------
# Reverse Prediction Setup
# ---------------------------
crops = [
'ਚੌਲ',
'ਮੱਕੀ',
'ਛੋਲੇ',
'ਰਾਜ਼ਮਾ',
'ਅਰਹਰ ਦੀ ਦਾਲ',
'ਮੋਠ ਦੀ ਦਾਲ',
'ਮੂੰਗ ਦੀ ਦਾਲ',
'ਮਾਂਹ ਦੀ ਦਾਲ',
'ਮਸਰ ਦੀ ਦਾਲ',
'ਅਨਾਰ',
'ਕੇਲਾ',
'ਅੰਬ',
'ਤਰਬੂਜ਼',
'ਖਰਬੂਜ਼ਾ',
'ਸੰਤਰਾ',
'ਪਪੀਤਾ',
'ਨਾਰੀਅਲ',
'ਕਪਾਹ',
'ਜੂਟ',
'ਕੌਫ਼ੀ'
]
data['crop_encoded'] = le.transform(data['label'])
reverse_X = data[['crop_encoded']]
y_cols = ['ਨਾਈਟ੍ਰੋਜਨ (kg/ha)', 'ਫਾਸਫੋਰਸ (kg/ha)', 'ਪੋਟਾਸ਼ੀਅਮ (kg/ha)', 'ਤਾਪਮਾਨ (°C)', 'ਨਮੀ (%)', 'ਮਿੱਟੀ ਦਾ pH', 'ਵਰਖਾ (mm)']
reverse_models = {}
for col in y_cols:
y = data[col]
X_train, X_test, y_train, y_test = train_test_split(reverse_X, y, test_size=0.2, random_state=42)
model_r = lgb.LGBMRegressor()
model_r.fit(X_train, y_train)
reverse_models[col] = model_r
label_to_encoded = {label: le.transform([label])[0] for label in le.classes_}
def predict_crop_parameters(crop_name):
crop_name_lower = crop_name.lower()
if crop_name_lower not in label_to_encoded:
return f"❌ '{crop_name}' ਲਈ ਡਾਟਾ ਨਹੀਂ ਮਿਲਿਆ।"
encoded_value = label_to_encoded[crop_name_lower]
input_data = [[encoded_value]]
predictions = {}
for param, model_r in reverse_models.items():
predicted_value = model_r.predict(input_data)[0]
predictions[param] = round(predicted_value, 2)
# Format output as markdown (clean readable list)
formatted_output = "\n".join([f"{k}: {v}" for k, v in predictions.items()])
return formatted_output
def predict_crop_parameters(crop_name):
crop_name_lower = crop_name.lower()
if crop_name_lower not in label_to_encoded:
return f"❌ '{crop_name}' ਲਈ ਡਾਟਾ ਨਹੀਂ ਮਿਲਿਆ।"
encoded_value = label_to_encoded[crop_name_lower]
input_data = [[encoded_value]]
predictions = {}
for param, model_r in reverse_models.items():
predicted_value = model_r.predict(input_data)[0]
predictions[param] = round(predicted_value, 2)
formatted_output = ""
for k, v in predictions.items():
formatted_output += f"{k}: {v}
"
return formatted_output
# ---------------------------
# Voice to Text Utility
# ---------------------------
def transcribe_audio(audio_path):
recognizer = sr.Recognizer()
with sr.AudioFile(audio_path) as source:
audio = recognizer.record(source)
try:
return recognizer.recognize_google(audio, language='pa-IN')
except sr.UnknownValueError:
return "❌ ਆਵਾਜ਼ ਨੂੰ ਸਮਝਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ।"
except sr.RequestError:
return "❌ ਗੂਗਲ ਸਪੀਚ ਐਪੀਆਈ ਨਾਲ ਕਨੇਕਟ ਨਹੀਂ ਹੋ ਸਕਿਆ।"
# ---------------------------
# Gemini Response & TTS
# ---------------------------
def get_gemini_response(query):
try:
response = gemini_model.generate_content(f"ਪੰਜਾਬੀ ਵਿੱਚ ਜਵਾਬ ਦਿਓ: {query}")
return response.text
except Exception as e:
return f"❌ Gemini ਤਰਫੋਂ ਗਲਤੀ: {str(e)}"
def text_to_speech(text, lang='pa'):
tts = gTTS(text=text, lang=lang)
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
tts.save(temp_file.name)
return temp_file.name
# ---------------------------
# Combined Function
# ---------------------------
def handle_voice_query(audio_file):
query = transcribe_audio(audio_file)
response = get_gemini_response(query)
audio_path = text_to_speech(response)
return query, response, audio_path
# ---------------------------
# Plant Disease Detection
# ---------------------------
# Set device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# Paths to files
model_path = "mobilenetv3_plant_disease.pth"
class_names_path = "class_labels.json"
# Load model
model_disease = models.mobilenet_v3_small(pretrained=False)
model_disease.classifier[3] = torch.nn.Linear(model_disease.classifier[3].in_features, 38)
model_disease.load_state_dict(torch.load(model_path, map_location=device))
model_disease.to(device)
model_disease.eval()
# Load and reverse class names
with open(class_names_path, 'r') as f:
label_to_index = json.load(f)
index_to_label = {v: k for k, v in label_to_index.items()}
# Define transform
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor()
])
# Prediction function
def predict_disease(image_path):
try:
image = Image.open(image_path).convert("RGB")
img_tensor = transform(image).unsqueeze(0).to(device)
with torch.no_grad():
outputs = model_disease(img_tensor)
_, predicted = torch.max(outputs, 1)
predicted_class = predicted.item()
class_name = index_to_label.get(predicted_class, "Unknown class")
return f"🌿 Predicted Disease: *{class_name.replace('_', ' ')}*"
except Exception as e:
return f"❌ Prediction Failed: {str(e)}"
# ---------------------------
# Gradio Interface
# ---------------------------
with gr.Blocks() as demo:
gr.Markdown("# 🌾 **AgroVision: ਪੰਜਾਬੀ ਵੈਚਲਣ ਸਹਾਇਕ**")
with gr.Tabs():
with gr.TabItem("🌾ਕਿਹੜੀ ਫਸਲ ਲਾਈਏ? "):
with gr.Row():
ਨਾਈਟ੍ਰੋਜਨ= gr.Slider(0, 140, step=1, label="ਨਾਈਟ੍ਰੋਜਨ (kg/ha)")
ਫਾਸਫੋਰਸ= gr.Slider(5, 95, step=1, label="ਫਾਸਫੋਰਸ (kg/ha)")
ਪੋਟਾਸ਼ੀਅਮ= gr.Slider(5, 82, step=1, label="ਪੋਟਾਸ਼ੀਅਮ (kg/ha)")
with gr.Row():
ਤਾਪਮਾਨ= gr.Slider(15.63, 36.32, step=0.1, label="ਤਾਪਮਾਨ (°C)")
ਨਮੀ= gr.Slider(14.2,99.98 , step=1, label="ਨਮੀ (%)")
with gr.Row():
ਮਿੱਟੀ_pH= gr.Slider(0, 14, step=0.1, label="ਮਿੱਟੀ ਦਾ pH")
ਵਰਖਾ= gr.Slider(20.21, 253.72, step=1, label="ਵਰਖਾ (mm)")
predict_btn = gr.Button("ਫਸਲ ਦੀ ਭਵਿੱਖਬਾਣੀ ਕਰੋ")
crop_image_output = gr.Image(label="🌿 ਫਸਲ ਦੀ ਤਸਵੀਰ")
crop_text_output = gr.Markdown()
predict_btn.click(fn=predict_crop,
inputs=[ਨਾਈਟ੍ਰੋਜਨ,ਫਾਸਫੋਰਸ,ਪੋਟਾਸ਼ੀਅਮ,ਤਾਪਮਾਨ,ਨਮੀ,ਮਿੱਟੀ_pH,ਵਰਖਾ],
outputs=[crop_image_output, crop_text_output])
with gr.TabItem("🔁 ਫਸਲ ਤੋਂ ਪੈਰਾਮੀਟਰ"):
crop_input = gr.Dropdown(choices=crops, label="🌿 ਫਸਲ ਦਾ ਨਾਂ ਲਿਖੋ")
result_output = gr.Markdown(label="🧪 ਅਨੁਕੂਲ ਪੈਰਾਮੀਟਰ")
run_btn = gr.Button("➡️ ਭਵਿੱਖਬਾਣੀ ਲਵੋ")
run_btn.click(fn=predict_crop_parameters, inputs=[crop_input], outputs=[result_output])
with gr.TabItem("🗣️ ਆਵਾਜ਼ ਰਾਹੀਂ ਪੁੱਛੋ"):
gr.Markdown("### ਆਪਣਾ ਸਵਾਲ ਆਵਾਜ਼ ਰਾਹੀਂ ਪੁੱਛੋ (ਪੰਜਾਬੀ ਵਿੱਚ)")
audio_input = gr.Audio(type="filepath", label="🎤 ਸਵਾਲ ਬੋਲੋ")
query_text = gr.Textbox(label="🔍 ਬੋਲਿਆ ਗਿਆ ਸਵਾਲ")
gemini_response = gr.Textbox(label="📜 Gemini ਜਵਾਬ")
audio_output = gr.Audio(label="🔊 ਆਵਾਜ਼ੀ ਜਵਾਬ")
submit_btn = gr.Button("➡️ ਜਵਾਬ ਲਵੋ")
submit_btn.click(fn=handle_voice_query, inputs=[audio_input], outputs=[query_text, gemini_response, audio_output])
with gr.TabItem("Plant Disease Detection"):
gr.Markdown("### Upload a crop leaf image to detect disease")
image_input = gr.Image(type="filepath", label="📷 Upload Leaf Image")
disease_btn = gr.Button("Detect Disease")
disease_output = gr.Markdown()
disease_btn.click(fn=predict_disease, inputs=image_input, outputs=disease_output)
demo.launch()