luigi12345 commited on
Commit
c73c262
β€’
1 Parent(s): 4234218
Files changed (1) hide show
  1. app.py +112 -26
app.py CHANGED
@@ -183,30 +183,58 @@ def save_results(results, original_images):
183
  def main():
184
  st.set_page_config(layout="wide", page_title="Glaucoma Screening Tool")
185
 
 
 
186
  st.markdown("""
187
  <h1 style='text-align: center;'>Glaucoma Screening from Retinal Fundus Images</h1>
188
  <p style='text-align: center; color: gray;'>Upload retinal images for automated glaucoma detection and optic disc/cup segmentation</p>
189
  """, unsafe_allow_html=True)
190
 
191
- # Sidebar settings
192
- st.sidebar.markdown("### Upload Settings")
193
- uploaded_files = st.sidebar.file_uploader("Upload Retinal Images",
194
- type=['png', 'jpeg', 'jpg'],
195
- accept_multiple_files=True,
196
- help="Support multiple images in PNG, JPEG formats")
197
 
198
- st.sidebar.markdown("### Analysis Settings")
199
- st.sidebar.info("πŸ“Š Set confidence threshold to filter results")
200
- confidence_threshold = st.sidebar.slider(
201
- "Classification Confidence Threshold (%)",
202
- 0, 100, 70,
203
- help="Images with confidence above this threshold will be marked as reliable predictions")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
  if uploaded_files:
206
- st.markdown("## πŸ“Š Batch Analysis Results")
 
 
 
 
 
 
 
207
 
208
- # Initialize model once for all images
209
- model = GlaucomaModel(device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu"))
 
 
 
 
210
 
211
  # Prepare images data
212
  images_data = []
@@ -228,20 +256,44 @@ def main():
228
  results = process_batch(model, images_data, progress_bar)
229
 
230
  if results:
231
- # Generate ZIP with results
232
- zip_data = save_results(results, original_images)
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
234
- # Download button for ZIP
235
- st.download_button(
236
- label="πŸ“₯ Download All Results",
237
- data=zip_data,
238
- file_name=f"glaucoma_screening_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip",
239
- mime="application/zip"
240
  )
241
 
242
- # Display results
243
- for result in results:
244
- with st.expander(f"Results for {result['file_name']}"):
 
 
 
 
 
 
 
 
 
 
 
245
  cols = st.columns(3)
246
  with cols[0]:
247
  st.image(result['processed_image'], caption="Segmentation", use_column_width=True)
@@ -254,3 +306,37 @@ def main():
254
  st.write(f"VCDR: {result['vcdr']:.3f}")
255
  st.write(f"Cup Confidence: {result['cup_conf']:.1f}%")
256
  st.write(f"Disc Confidence: {result['disc_conf']:.1f}%")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  def main():
184
  st.set_page_config(layout="wide", page_title="Glaucoma Screening Tool")
185
 
186
+ print("Starting app...") # Debug print
187
+
188
  st.markdown("""
189
  <h1 style='text-align: center;'>Glaucoma Screening from Retinal Fundus Images</h1>
190
  <p style='text-align: center; color: gray;'>Upload retinal images for automated glaucoma detection and optic disc/cup segmentation</p>
191
  """, unsafe_allow_html=True)
192
 
193
+ print("Header rendered...") # Debug print
 
 
 
 
 
194
 
195
+ # Add session state for better state management
196
+ if 'processed_count' not in st.session_state:
197
+ st.session_state.processed_count = 0
198
+
199
+ # Add a more informative sidebar
200
+ with st.sidebar:
201
+ st.markdown("### πŸ“€ Upload Images")
202
+ uploaded_files = st.file_uploader(
203
+ "Upload Retinal Images",
204
+ type=['png', 'jpeg', 'jpg'],
205
+ accept_multiple_files=True,
206
+ help="Support multiple images in PNG, JPEG formats"
207
+ )
208
+
209
+ st.markdown("### πŸ“Š Processing Stats")
210
+ if 'processed_count' in st.session_state:
211
+ st.metric("Images Processed", st.session_state.processed_count)
212
+
213
+ st.markdown("---")
214
+
215
+ # Add batch size limit
216
+ max_batch = st.number_input("Max Batch Size",
217
+ min_value=1,
218
+ max_value=100,
219
+ value=20,
220
+ help="Maximum number of images to process in one batch")
221
 
222
  if uploaded_files:
223
+ # Validate batch size
224
+ if len(uploaded_files) > max_batch:
225
+ st.warning(f"⚠️ Please upload maximum {max_batch} images at once. Current: {len(uploaded_files)}")
226
+ return
227
+
228
+ # Add loading animation
229
+ with st.spinner('πŸ”„ Initializing model...'):
230
+ model = GlaucomaModel(device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu"))
231
 
232
+ # Add summary metrics at the top
233
+ col1, col2 = st.columns(2)
234
+ with col1:
235
+ st.info(f"πŸ“ Total images: {len(uploaded_files)}")
236
+ with col2:
237
+ st.info(f"βš™οΈ Using: {'GPU' if torch.cuda.is_available() else 'CPU'}")
238
 
239
  # Prepare images data
240
  images_data = []
 
256
  results = process_batch(model, images_data, progress_bar)
257
 
258
  if results:
259
+ # Add summary statistics
260
+ st.markdown("### πŸ“Š Summary Statistics")
261
+ glaucoma_count = sum(1 for r in results if r['diagnosis'] == 'Glaucoma')
262
+ normal_count = len(results) - glaucoma_count
263
+
264
+ cols = st.columns(4)
265
+ with cols[0]:
266
+ st.metric("Total Processed", len(results))
267
+ with cols[1]:
268
+ st.metric("Glaucoma Detected", glaucoma_count)
269
+ with cols[2]:
270
+ st.metric("Normal", normal_count)
271
+ with cols[3]:
272
+ avg_conf = sum(r['confidence'] for r in results) / len(results)
273
+ st.metric("Avg Confidence", f"{avg_conf:.1f}%")
274
 
275
+ # Add filter options
276
+ st.markdown("### πŸ” Filter Results")
277
+ show_only = st.multiselect(
278
+ "Show cases:",
279
+ ["All", "Glaucoma", "Normal"],
280
+ default=["All"]
281
  )
282
 
283
+ # Filter results based on selection
284
+ filtered_results = results
285
+ if "All" not in show_only:
286
+ filtered_results = [
287
+ r for r in results
288
+ if (r['diagnosis'] == 'Glaucoma' and 'Glaucoma' in show_only) or
289
+ (r['diagnosis'] == 'Normal' and 'Normal' in show_only)
290
+ ]
291
+
292
+ # Display filtered results
293
+ for result in filtered_results:
294
+ with st.expander(
295
+ f"πŸ“‹ {result['file_name']} - {result['diagnosis']} ({result['confidence']:.1f}% confidence)"
296
+ ):
297
  cols = st.columns(3)
298
  with cols[0]:
299
  st.image(result['processed_image'], caption="Segmentation", use_column_width=True)
 
306
  st.write(f"VCDR: {result['vcdr']:.3f}")
307
  st.write(f"Cup Confidence: {result['cup_conf']:.1f}%")
308
  st.write(f"Disc Confidence: {result['disc_conf']:.1f}%")
309
+
310
+ # Update session state
311
+ st.session_state.processed_count += len(results)
312
+
313
+ # Add export options
314
+ st.markdown("### πŸ“₯ Export Options")
315
+ col1, col2 = st.columns(2)
316
+ with col1:
317
+ st.download_button(
318
+ label="πŸ“₯ Download All Results (ZIP)",
319
+ data=zip_data,
320
+ file_name=f"glaucoma_screening_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip",
321
+ mime="application/zip"
322
+ )
323
+ with col2:
324
+ # Add CSV-only download
325
+ csv_data = pd.DataFrame([{
326
+ 'File': r['file_name'],
327
+ 'Diagnosis': r['diagnosis'],
328
+ 'Confidence': r['confidence'],
329
+ 'VCDR': r['vcdr']
330
+ } for r in results]).to_csv(index=False)
331
+
332
+ st.download_button(
333
+ label="πŸ“Š Download Report (CSV)",
334
+ data=csv_data,
335
+ file_name=f"glaucoma_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
336
+ mime="text/csv"
337
+ )
338
+
339
+ # Add this at the end of the file
340
+ if __name__ == "__main__":
341
+ print("Running main...") # Debug print
342
+ main()