edcelbogs commited on
Commit
ec072b2
ยท
verified ยท
1 Parent(s): cc23aa1

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +18 -72
src/streamlit_app.py CHANGED
@@ -1,4 +1,5 @@
1
  import streamlit as st
 
2
  import requests
3
  from PIL import Image
4
  import tempfile
@@ -16,23 +17,18 @@ st.set_page_config(page_title="Cassava Disease Detection", layout="centered")
16
  # -----------------------------
17
  ROBOFLOW_API_KEY = st.secrets["ROBOFLOW_API_KEY"]
18
  OPENROUTER_API_KEY = st.secrets["OPENROUTER_API_KEY"]
19
-
20
  MODEL_ID = "cassavadisease/1"
21
- ROBOFLOW_API_URL = "https://serverless.roboflow.com"
22
 
23
  # -----------------------------
24
- # INITIALIZE ROBOFLOW CLIENT
25
  # -----------------------------
26
- CLIENT = InferenceHTTPClient(
27
- api_url=ROBOFLOW_API_URL,
28
- api_key=ROBOFLOW_API_KEY
29
- )
30
 
31
  # -----------------------------
32
  # FUNCTION: AI EXPLANATION
33
  # -----------------------------
34
  def get_ai_explanation(disease_name):
35
-
36
  prompt = f"""
37
  Explain briefly the cassava disease: {disease_name}.
38
  Include:
@@ -42,35 +38,8 @@ def get_ai_explanation(disease_name):
42
  - Treatment
43
  Keep answer short.
44
  """
45
-
46
- response = requests.post(
47
- "https://openrouter.ai/api/v1/chat/completions",
48
- headers={
49
- "Authorization": f"Bearer {OPENROUTER_API_KEY}",
50
- "Content-Type": "application/json",
51
- "HTTP-Referer": "http://localhost:8501",
52
- "X-Title": "Cassava Disease Detection App"
53
- },
54
- json={
55
- "model": "minimax/minimax-m2.5",
56
- "messages": [
57
- {"role": "user", "content": prompt}
58
- ],
59
- "max_tokens": 800,
60
- "temperature": 0.3
61
- }
62
- )
63
-
64
- if response.status_code != 200:
65
- return f"OpenRouter API Error:\n{response.text}"
66
-
67
- result = response.json()
68
-
69
- if "choices" not in result:
70
- return f"Unexpected API Response:\n{result}"
71
-
72
- return result["choices"][0]["message"]["content"]
73
-
74
 
75
  # -----------------------------
76
  # UI
@@ -79,14 +48,12 @@ st.title("Cassava Disease Detection Web App")
79
  st.write("Upload or capture a cassava leaf image for disease detection.")
80
 
81
  source = st.radio("Select Image Source:", ["Upload Image", "Use Camera"])
82
-
83
  image = None
84
 
85
  if source == "Upload Image":
86
  uploaded_file = st.file_uploader("Upload Image", type=["jpg", "jpeg", "png"])
87
  if uploaded_file:
88
  image = Image.open(uploaded_file)
89
-
90
  elif source == "Use Camera":
91
  camera_photo = st.camera_input("Take a picture of the cassava leaf")
92
  if camera_photo:
@@ -96,7 +63,6 @@ elif source == "Use Camera":
96
  # MAIN PROCESS
97
  # -----------------------------
98
  if image is not None:
99
-
100
  st.image(image, caption="Captured Image", use_container_width=True)
101
 
102
  # Save temp image
@@ -104,56 +70,40 @@ if image is not None:
104
  image.save(tmp.name)
105
  temp_path = tmp.name
106
 
107
- # Roboflow inference
 
 
108
  with st.spinner("Analyzing image..."):
109
- result = CLIENT.infer(temp_path, model_id=MODEL_ID)
110
-
 
 
 
111
  os.remove(temp_path)
112
-
113
  predictions = result.get("predictions", [])
114
-
115
  if predictions:
116
-
117
  img_cv = np.array(image)
118
  img_cv = cv2.cvtColor(img_cv, cv2.COLOR_RGB2BGR)
119
 
120
  for pred in predictions:
121
-
122
- x = pred["x"]
123
- y = pred["y"]
124
- w = pred["width"]
125
- h = pred["height"]
126
  label = pred["class"]
127
  confidence = round(pred["confidence"] * 100, 2)
128
 
129
- # Convert center to corner format
130
  x1 = int(x - w / 2)
131
  y1 = int(y - h / 2)
132
  x2 = int(x + w / 2)
133
  y2 = int(y + h / 2)
134
 
135
- # Draw bounding box
136
  cv2.rectangle(img_cv, (x1, y1), (x2, y2), (0, 255, 0), 2)
137
-
138
- # Label background
139
  cv2.rectangle(img_cv, (x1, y1 - 30), (x1 + 250, y1), (0, 255, 0), -1)
 
140
 
141
- # Label text
142
- cv2.putText(
143
- img_cv,
144
- f"{label} ({confidence}%)",
145
- (x1 + 5, y1 - 10),
146
- cv2.FONT_HERSHEY_SIMPLEX,
147
- 0.6,
148
- (0, 0, 0),
149
- 2
150
- )
151
-
152
- # Convert back to RGB
153
  img_display = cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB)
154
  st.image(img_display, caption="Detected & Labeled Image", use_container_width=True)
155
 
156
- # Get highest confidence prediction
157
  top_prediction = max(predictions, key=lambda x: x["confidence"])
158
  disease_name = top_prediction["class"]
159
  confidence = round(top_prediction["confidence"] * 100, 2)
@@ -161,17 +111,13 @@ if image is not None:
161
  st.success(f"Detected: **{disease_name}**")
162
  st.info(f"Confidence: {confidence}%")
163
 
164
- # AI Explanation
165
  with st.spinner("Generating disease explanation..."):
166
  explanation = get_ai_explanation(disease_name)
167
-
168
  st.markdown("## ๐Ÿ“˜ Disease Information")
169
  st.write(explanation)
170
-
171
  else:
172
  st.warning("No cassava leaf detected.")
173
 
174
-
175
  # -----------------------------
176
  # FOOTER
177
  # -----------------------------
 
1
  import streamlit as st
2
+ from huggingface_hub import InferenceClient
3
  import requests
4
  from PIL import Image
5
  import tempfile
 
17
  # -----------------------------
18
  ROBOFLOW_API_KEY = st.secrets["ROBOFLOW_API_KEY"]
19
  OPENROUTER_API_KEY = st.secrets["OPENROUTER_API_KEY"]
 
20
  MODEL_ID = "cassavadisease/1"
21
+ ROBOFLOW_API_URL = "https://detect.roboflow.com"
22
 
23
  # -----------------------------
24
+ # INITIALIZE HF INFERENCE CLIENT
25
  # -----------------------------
26
+ hf_client = InferenceClient(token=OPENROUTER_API_KEY)
 
 
 
27
 
28
  # -----------------------------
29
  # FUNCTION: AI EXPLANATION
30
  # -----------------------------
31
  def get_ai_explanation(disease_name):
 
32
  prompt = f"""
33
  Explain briefly the cassava disease: {disease_name}.
34
  Include:
 
38
  - Treatment
39
  Keep answer short.
40
  """
41
+ response = hf_client.chat(model="minimax/minimax-m2.5", inputs=prompt)
42
+ return response.get("generated_text") if "generated_text" in response else str(response)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  # -----------------------------
45
  # UI
 
48
  st.write("Upload or capture a cassava leaf image for disease detection.")
49
 
50
  source = st.radio("Select Image Source:", ["Upload Image", "Use Camera"])
 
51
  image = None
52
 
53
  if source == "Upload Image":
54
  uploaded_file = st.file_uploader("Upload Image", type=["jpg", "jpeg", "png"])
55
  if uploaded_file:
56
  image = Image.open(uploaded_file)
 
57
  elif source == "Use Camera":
58
  camera_photo = st.camera_input("Take a picture of the cassava leaf")
59
  if camera_photo:
 
63
  # MAIN PROCESS
64
  # -----------------------------
65
  if image is not None:
 
66
  st.image(image, caption="Captured Image", use_container_width=True)
67
 
68
  # Save temp image
 
70
  image.save(tmp.name)
71
  temp_path = tmp.name
72
 
73
+ # -----------------------------
74
+ # Roboflow inference (via requests)
75
+ # -----------------------------
76
  with st.spinner("Analyzing image..."):
77
+ headers = {"Authorization": f"Bearer {ROBOFLOW_API_KEY}"}
78
+ files = {"file": open(temp_path, "rb")}
79
+ response = requests.post(f"{ROBOFLOW_API_URL}/{MODEL_ID}", headers=headers, files=files)
80
+ result = response.json()
81
+
82
  os.remove(temp_path)
83
+
84
  predictions = result.get("predictions", [])
85
+
86
  if predictions:
 
87
  img_cv = np.array(image)
88
  img_cv = cv2.cvtColor(img_cv, cv2.COLOR_RGB2BGR)
89
 
90
  for pred in predictions:
91
+ x, y, w, h = pred["x"], pred["y"], pred["width"], pred["height"]
 
 
 
 
92
  label = pred["class"]
93
  confidence = round(pred["confidence"] * 100, 2)
94
 
 
95
  x1 = int(x - w / 2)
96
  y1 = int(y - h / 2)
97
  x2 = int(x + w / 2)
98
  y2 = int(y + h / 2)
99
 
 
100
  cv2.rectangle(img_cv, (x1, y1), (x2, y2), (0, 255, 0), 2)
 
 
101
  cv2.rectangle(img_cv, (x1, y1 - 30), (x1 + 250, y1), (0, 255, 0), -1)
102
+ cv2.putText(img_cv, f"{label} ({confidence}%)", (x1 + 5, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,0), 2)
103
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  img_display = cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB)
105
  st.image(img_display, caption="Detected & Labeled Image", use_container_width=True)
106
 
 
107
  top_prediction = max(predictions, key=lambda x: x["confidence"])
108
  disease_name = top_prediction["class"]
109
  confidence = round(top_prediction["confidence"] * 100, 2)
 
111
  st.success(f"Detected: **{disease_name}**")
112
  st.info(f"Confidence: {confidence}%")
113
 
 
114
  with st.spinner("Generating disease explanation..."):
115
  explanation = get_ai_explanation(disease_name)
 
116
  st.markdown("## ๐Ÿ“˜ Disease Information")
117
  st.write(explanation)
 
118
  else:
119
  st.warning("No cassava leaf detected.")
120
 
 
121
  # -----------------------------
122
  # FOOTER
123
  # -----------------------------