Spaces:
Sleeping
Sleeping
File size: 5,734 Bytes
19f9c62 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | import gradio as gr
import requests
from geopy.geocoders import Nominatim
from PIL import Image
import base64
import io
import os
import json
from duckduckgo_search import DDGS
# π OpenAI API Key (set in Hugging Face Space Secrets)
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
API_URL = "https://api.openai.com/v1/chat/completions"
# π Reverse geocode lat/lon β location name
def get_address(lat, lon):
geolocator = Nominatim(user_agent="farming_guidance")
try:
location = geolocator.reverse((lat, lon), language="en")
return location.address if location else "Unknown Location"
except:
return "Error fetching location"
# πΌοΈ Analyze crop & damage using GPT-4o Vision
def analyze_crop_image(image):
buffered = io.BytesIO()
image.save(buffered, format="PNG")
img_b64 = base64.b64encode(buffered.getvalue()).decode("utf-8")
vision_prompt = """
You are an agricultural vision expert. Carefully analyze this crop image.
- Identify the crop.
- State if Healthy or Damaged.
- If damaged, classify (pest / disease / nutrient deficiency).
- Suggest organic + inorganic treatments.
Return JSON only.
"""
headers = {"Authorization": f"Bearer {OPENAI_API_KEY}", "Content-Type": "application/json"}
data = {
"model": "gpt-4o",
"messages": [
{"role": "system", "content": "You are a professional agriculture crop doctor."},
{
"role": "user",
"content": [
{"type": "text", "text": vision_prompt},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img_b64}"}}
]
}
],
"temperature": 0.2
}
response = requests.post(API_URL, headers=headers, json=data)
if response.status_code == 200:
raw = response.json()["choices"][0]["message"]["content"]
try:
if "```json" in raw:
json_part = raw.split("```json")[1].split("```")[0].strip()
return json.loads(json_part)
return json.loads(raw)
except Exception:
return {"Crop": "Unknown", "Status": "Unknown", "Reason": "Parsing Error", "Raw": raw}
return {"Error": response.text}
# π Web search if detection confidence is low
def search_crop_disease(crop, symptom):
query = f"{crop} {symptom} disease treatment site:.org OR site:.gov OR site:.edu"
try:
with DDGS() as ddgs:
results = ddgs.text(query, max_results=3)
return [f"- {r['title']}: {r['body']} ({r['href']})" for r in results]
except Exception as e:
return [f"β Web search failed: {str(e)}"]
# π Advisory generator
def get_recommendations(image, lat, lon):
vision_result = analyze_crop_image(image)
crop = vision_result.get("Crop", "Unknown")
reason = vision_result.get("Reason", "Unclear")
confidence = vision_result.get("Confidence", "Low")
address = get_address(lat, lon)
soil_profile = "Loamy soil, moderate organic matter (default assumption)"
climate = f"Climate for Lat:{lat}, Lon:{lon} - Avg temp 27Β°C, humidity 70%, rainfall forecast: 15mm"
web_results = []
if confidence.lower() == "low" or crop == "Unknown":
web_results = search_crop_disease(crop, reason)
advisory_prompt = f"""
You are an agricultural advisor for Indian farmers.
Farmer details:
Location: {address} (Lat:{lat}, Lon:{lon})
Crop: {crop}
Soil: {soil_profile}
Climate: {climate}
Image Analysis: {vision_result}
Internet Search Findings: {web_results}
Give practical farmer guidance:
- Fertilizers (stage-wise dosage/acre).
- Pesticides (preventive + curative).
- Herbicides (safe use).
- Common pest/disease alerts in region.
- Alternative crops and secondary crops.
"""
headers = {"Authorization": f"Bearer {OPENAI_API_KEY}", "Content-Type": "application/json"}
data = {"model": "gpt-4o", "messages": [{"role": "user", "content": advisory_prompt}], "temperature": 0.5}
response = requests.post(API_URL, headers=headers, json=data)
if response.status_code == 200:
return (
f"πΌοΈ Image Analysis:\n{vision_result}\n\n"
f"π Web Search Support:\n" + "\n".join(web_results) +
f"\n\nπ Location: {address}\n\n" +
response.json()["choices"][0]["message"]["content"]
)
return f"β Error: {response.text}"
# π¨ Gradio UI
with gr.Blocks() as demo:
gr.Markdown("## π± AI Farming Guidance Platform (Lightweight Cropseetalk model with Internet Powered)")
with gr.Row():
image_input = gr.Image(type="pil", label="Upload Crop Image")
with gr.Row():
lat_box = gr.Number(label="Latitude", value=28.61)
lon_box = gr.Number(label="Longitude", value=77.23)
get_loc_btn = gr.Button("π Get Location from Device")
run_btn = gr.Button("π Analyze & Get Guidance")
output = gr.Textbox(label="Recommendations", lines=30)
get_loc_btn.click(
None,
js="""
() => new Promise((resolve, reject) => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(pos) => resolve([pos.coords.latitude, pos.coords.longitude]),
(err) => reject("Location access denied")
);
} else {
reject("Geolocation not supported");
}
})
""",
outputs=[lat_box, lon_box]
)
run_btn.click(fn=get_recommendations, inputs=[image_input, lat_box, lon_box], outputs=output)
if __name__ == "__main__":
demo.launch()
|