Sefat33 commited on
Commit
c138b4f
Β·
verified Β·
1 Parent(s): f980978

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -80
app.py CHANGED
@@ -51,49 +51,6 @@ def set_background(image_path):
51
 
52
  set_background("5858.jpg")
53
 
54
- # --- Custom CSS for layout and styling ---
55
- st.markdown("""
56
- <style>
57
- .stApp {
58
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
59
- }
60
- .preview-grid {
61
- display: grid;
62
- grid-template-columns: repeat(4, 1fr);
63
- gap: 1rem;
64
- margin-bottom: 2rem;
65
- }
66
- .preview-grid img {
67
- border-radius: 12px;
68
- box-shadow: 0 4px 10px rgba(0,0,0,0.15);
69
- max-width: 100%;
70
- height: auto;
71
- }
72
- .lime-row {
73
- display: flex;
74
- gap: 2rem;
75
- margin-top: 2rem;
76
- }
77
- .lime-row > div {
78
- flex: 1;
79
- }
80
- .overlay {
81
- background-color: rgba(255, 255, 255, 0.9);
82
- padding: 1rem 1.5rem;
83
- border-radius: 12px;
84
- font-size: 16px;
85
- box-shadow: 0 4px 10px rgba(0,0,0,0.1);
86
- height: 100%;
87
- }
88
- .sidebar .block-container {
89
- background-color: #f5f7fa;
90
- padding: 1rem;
91
- border-radius: 12px;
92
- box-shadow: 0 0 10px rgba(0,0,0,0.1);
93
- }
94
- </style>
95
- """, unsafe_allow_html=True)
96
-
97
  # --- Constants ---
98
  IMG_SIZE = (224, 224)
99
  CLASS_NAMES = [
@@ -148,20 +105,16 @@ def preprocess_with_steps(img):
148
  sharp = cv2.addWeighted(clahe_img, 4, cv2.GaussianBlur(clahe_img, (0, 0), 10), -4, 128)
149
  resized = cv2.resize(sharp, IMG_SIZE) / 255.0
150
 
151
- # Visualization with grid layout
152
- st.markdown("### πŸ” Preprocessing Steps")
153
- st.markdown('<div class="preview-grid">', unsafe_allow_html=True)
154
-
155
- for img_preview, title in zip(
156
- [img, circ, clahe_img, (resized * 255).astype(np.uint8)],
157
  ["Original", "Circular Crop", "CLAHE", "Sharpen + Resize"]
158
  ):
159
- buf = BytesIO()
160
- plt.imsave(buf, img_preview, format='png')
161
- st.image(buf.getvalue(), caption=title, use_container_width=True)
162
-
163
- st.markdown("</div>", unsafe_allow_html=True)
164
-
165
  return resized
166
 
167
  # --- Reasoning Text ---
@@ -196,44 +149,36 @@ def show_lime(img, model, pred_idx, pred_label, all_probs):
196
  buf.seek(0)
197
  lime_data = buf.getvalue()
198
 
199
- st.markdown("## 🧠 LIME Explanation & Reasoning")
200
- st.markdown('<div class="lime-row">', unsafe_allow_html=True)
201
-
202
  col1, col2 = st.columns(2)
203
  with col1:
204
- st.image(lime_data, caption="LIME Explanation", width=224)
205
- st.download_button("πŸ“₯ Download LIME Image", lime_data, file_name=f"{pred_label}_LIME.png", mime="image/png")
206
-
 
 
 
 
 
207
  with col2:
208
- st.markdown(f"<div class='overlay'>{explanation_text.get(pred_label, 'No explanation available.')}</div>", unsafe_allow_html=True)
209
-
210
- st.markdown("</div>", unsafe_allow_html=True)
 
211
 
212
- # --- Main App UI ---
213
  st.set_page_config(page_title="πŸ‘ Retina Classifier with LIME", layout="wide")
214
  st.title("πŸ‘ Retina Disease Classifier with LIME Explanation")
215
 
 
 
216
  with st.sidebar:
217
- st.header("πŸ“ Upload & Select")
218
  uploaded_files = st.file_uploader(
219
- "Upload retinal images", type=["jpg", "jpeg", "png"], accept_multiple_files=True
220
  )
221
  selected_filename = None
222
  if uploaded_files:
223
  filenames = [f.name for f in uploaded_files]
224
- selected_filename = st.selectbox("🎯 Choose an image", filenames)
225
-
226
- st.markdown("---")
227
- st.markdown("ℹ️ **App Info**")
228
- st.markdown("""
229
- This app detects retinal diseases using a deep learning model and explains the decision using **LIME**.
230
-
231
- Model: `CoAtNet / SavedModel`
232
-
233
- Accuracy: ~92%
234
- """)
235
-
236
- model = load_model()
237
 
238
  if uploaded_files and selected_filename:
239
  file = next(f for f in uploaded_files if f.name == selected_filename)
@@ -241,6 +186,7 @@ if uploaded_files and selected_filename:
241
  bgr = cv2.imdecode(np.frombuffer(file.read(), np.uint8), cv2.IMREAD_COLOR)
242
  rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
243
 
 
244
  preprocessed = preprocess_with_steps(rgb)
245
  input_tensor = np.expand_dims(preprocessed, axis=0)
246
 
 
51
 
52
  set_background("5858.jpg")
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  # --- Constants ---
55
  IMG_SIZE = (224, 224)
56
  CLASS_NAMES = [
 
105
  sharp = cv2.addWeighted(clahe_img, 4, cv2.GaussianBlur(clahe_img, (0, 0), 10), -4, 128)
106
  resized = cv2.resize(sharp, IMG_SIZE) / 255.0
107
 
108
+ fig, axs = plt.subplots(1, 4, figsize=(16, 4))
109
+ for ax, image, title in zip(
110
+ axs, [img, circ, clahe_img, resized],
 
 
 
111
  ["Original", "Circular Crop", "CLAHE", "Sharpen + Resize"]
112
  ):
113
+ ax.imshow(image)
114
+ ax.set_title(title)
115
+ ax.axis("off")
116
+ st.pyplot(fig)
117
+ plt.close(fig)
 
118
  return resized
119
 
120
  # --- Reasoning Text ---
 
149
  buf.seek(0)
150
  lime_data = buf.getvalue()
151
 
 
 
 
152
  col1, col2 = st.columns(2)
153
  with col1:
154
+ st.markdown("### πŸ“ LIME Explanation")
155
+ st.image(lime_data, width=224, output_format="PNG") # πŸ‘ˆ Small LIME image
156
+ st.download_button(
157
+ "πŸ“₯ Download LIME Image",
158
+ lime_data,
159
+ file_name=f"{pred_label}_LIME.png",
160
+ mime="image/png"
161
+ )
162
  with col2:
163
+ st.markdown(
164
+ f"<div class='overlay'>{explanation_text.get(pred_label, 'No explanation available.')}</div>",
165
+ unsafe_allow_html=True
166
+ )
167
 
168
+ # --- Streamlit App UI ---
169
  st.set_page_config(page_title="πŸ‘ Retina Classifier with LIME", layout="wide")
170
  st.title("πŸ‘ Retina Disease Classifier with LIME Explanation")
171
 
172
+ model = load_model()
173
+
174
  with st.sidebar:
 
175
  uploaded_files = st.file_uploader(
176
+ "πŸ“‚ Upload retinal images", type=["jpg", "jpeg", "png"], accept_multiple_files=True
177
  )
178
  selected_filename = None
179
  if uploaded_files:
180
  filenames = [f.name for f in uploaded_files]
181
+ selected_filename = st.selectbox("🎯 Select an image to explain", filenames)
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
  if uploaded_files and selected_filename:
184
  file = next(f for f in uploaded_files if f.name == selected_filename)
 
186
  bgr = cv2.imdecode(np.frombuffer(file.read(), np.uint8), cv2.IMREAD_COLOR)
187
  rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
188
 
189
+ st.subheader("πŸ” Preprocessing Steps")
190
  preprocessed = preprocess_with_steps(rgb)
191
  input_tensor = np.expand_dims(preprocessed, axis=0)
192