luigi12345 commited on
Commit
c4921c6
β€’
1 Parent(s): 56a1577
Files changed (1) hide show
  1. app.py +76 -18
app.py CHANGED
@@ -14,19 +14,28 @@ import os
14
  import tempfile
15
  import base64
16
 
 
 
 
 
 
 
17
  # --- GlaucomaModel Class ---
18
  class GlaucomaModel(object):
19
  def __init__(self,
20
  cls_model_path="pamixsun/swinv2_tiny_for_glaucoma_classification",
21
- seg_model_path='pamixsun/segformer_for_optic_disc_cup_segmentation',
22
  device=torch.device('cpu')):
23
  self.device = device
24
- # Classification model for glaucoma
25
  self.cls_extractor = AutoImageProcessor.from_pretrained(cls_model_path)
26
  self.cls_model = Swinv2ForImageClassification.from_pretrained(cls_model_path).to(device).eval()
27
- # Segmentation model for optic disc and cup
28
- self.seg_extractor = AutoImageProcessor.from_pretrained(seg_model_path)
29
- self.seg_model = SegformerForSemanticSegmentation.from_pretrained(seg_model_path).to(device).eval()
 
 
 
30
  # Mapping for class labels
31
  self.cls_id2label = self.cls_model.config.id2label
32
 
@@ -104,15 +113,15 @@ def add_mask(image, mask, classes, colors, alpha=0.5):
104
  def get_confidence_level(confidence):
105
  """Enhanced confidence descriptions for segmentation"""
106
  if confidence >= 90:
107
- return "Excellent (Very clear boundaries)"
108
  elif confidence >= 75:
109
- return "Good (Clear boundaries)"
110
  elif confidence >= 60:
111
- return "Fair (Visible but some unclear areas)"
112
  elif confidence >= 45:
113
- return "Poor (Difficult to determine)"
114
  else:
115
- return "Very Poor (Not reliable)"
116
 
117
  def process_batch(model, images_data, progress_bar=None):
118
  results = []
@@ -190,7 +199,14 @@ def main():
190
  st.title("Glaucoma Screening from Retinal Fundus Images")
191
  st.write("Upload retinal images for automated glaucoma detection and optic disc/cup segmentation")
192
 
193
- # Sidebar using old method
 
 
 
 
 
 
 
194
  st.sidebar.title("Upload Images")
195
  st.set_option('deprecation.showfileUploaderEncoding', False) # Important for old versions
196
  uploaded_files = st.sidebar.file_uploader(
@@ -208,15 +224,27 @@ def main():
208
  """)
209
 
210
  if uploaded_files:
211
- st.write("Loading AI models...")
212
-
213
  try:
214
- model = GlaucomaModel(device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
 
216
  for file in uploaded_files:
217
  try:
218
- # Process each image
219
- st.write(f"Processing: {file.name}")
220
  image = Image.open(file).convert('RGB')
221
  image_np = np.array(image)
222
 
@@ -232,11 +260,41 @@ def main():
232
  st.write(f"β€’ Finding: {model.cls_id2label[disease_idx]}")
233
  st.write(f"β€’ AI Confidence: {cls_conf:.1f}% ({get_confidence_level(cls_conf)})")
234
 
235
- # Segmentation confidence section
236
- st.write("\nπŸ” **Segmentation Quality:**")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  st.write(f"β€’ Optic Cup Detection: {cup_conf:.1f}% - {get_confidence_level(cup_conf)}")
238
  st.write(f"β€’ Optic Disc Detection: {disc_conf:.1f}% - {get_confidence_level(disc_conf)}")
239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  # Clinical metrics
241
  st.write("\nπŸ“ **Clinical Measurements:**")
242
  st.write(f"β€’ Cup-to-Disc Ratio (VCDR): {vcdr:.3f}")
 
14
  import tempfile
15
  import base64
16
 
17
+ # Add at the top with other constants
18
+ MODEL_OPTIONS = {
19
+ "Default (ferferefer/segformer)": "ferferefer/segformer",
20
+ "Pamixsun": "pamixsun/segformer_for_optic_disc_cup_segmentation"
21
+ }
22
+
23
  # --- GlaucomaModel Class ---
24
  class GlaucomaModel(object):
25
  def __init__(self,
26
  cls_model_path="pamixsun/swinv2_tiny_for_glaucoma_classification",
27
+ seg_model_path=None, # Make this optional
28
  device=torch.device('cpu')):
29
  self.device = device
30
+ # Classification model for glaucoma (always the same)
31
  self.cls_extractor = AutoImageProcessor.from_pretrained(cls_model_path)
32
  self.cls_model = Swinv2ForImageClassification.from_pretrained(cls_model_path).to(device).eval()
33
+
34
+ # Segmentation model - use provided path or default
35
+ seg_path = seg_model_path or MODEL_OPTIONS["Pamixsun"] # Default to Pamixsun if none provided
36
+ self.seg_extractor = AutoImageProcessor.from_pretrained(seg_path)
37
+ self.seg_model = SegformerForSemanticSegmentation.from_pretrained(seg_path).to(device).eval()
38
+
39
  # Mapping for class labels
40
  self.cls_id2label = self.cls_model.config.id2label
41
 
 
113
  def get_confidence_level(confidence):
114
  """Enhanced confidence descriptions for segmentation"""
115
  if confidence >= 90:
116
+ return "Excellent (Model is very certain about the detected boundaries)"
117
  elif confidence >= 75:
118
+ return "Good (Model is confident about most of the detected area)"
119
  elif confidence >= 60:
120
+ return "Fair (Model has some uncertainty in parts of the detection)"
121
  elif confidence >= 45:
122
+ return "Poor (Model is uncertain about many detected areas)"
123
  else:
124
+ return "Very Poor (Model's detection is highly uncertain)"
125
 
126
  def process_batch(model, images_data, progress_bar=None):
127
  results = []
 
199
  st.title("Glaucoma Screening from Retinal Fundus Images")
200
  st.write("Upload retinal images for automated glaucoma detection and optic disc/cup segmentation")
201
 
202
+ # Add model selection in sidebar before file upload
203
+ st.sidebar.title("Model Settings")
204
+ selected_model = st.sidebar.selectbox(
205
+ "Select Segmentation Model",
206
+ list(MODEL_OPTIONS.keys()),
207
+ index=1 # Default to Pamixsun
208
+ )
209
+
210
  st.sidebar.title("Upload Images")
211
  st.set_option('deprecation.showfileUploaderEncoding', False) # Important for old versions
212
  uploaded_files = st.sidebar.file_uploader(
 
224
  """)
225
 
226
  if uploaded_files:
 
 
227
  try:
228
+ # Enhanced model loading feedback
229
+ st.write("πŸ€– Initializing AI models...")
230
+ st.write(f"β€’ Loading classification model: pamixsun/swinv2_tiny_for_glaucoma_classification")
231
+ st.write(f"β€’ Loading segmentation model: {selected_model}")
232
+
233
+ # Initialize model with selected segmentation model
234
+ model = GlaucomaModel(
235
+ device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu"),
236
+ seg_model_path=MODEL_OPTIONS[selected_model]
237
+ )
238
+
239
+ # Show model loading completion
240
+ st.write("βœ… Models loaded successfully")
241
+ st.write(f"πŸ–₯️ Using: {'GPU' if torch.cuda.is_available() else 'CPU'} for processing")
242
+ st.write("---")
243
 
244
  for file in uploaded_files:
245
  try:
246
+ # Process each image with enhanced feedback
247
+ st.write(f"πŸ“Έ Processing image: {file.name}")
248
  image = Image.open(file).convert('RGB')
249
  image_np = np.array(image)
250
 
 
260
  st.write(f"β€’ Finding: {model.cls_id2label[disease_idx]}")
261
  st.write(f"β€’ AI Confidence: {cls_conf:.1f}% ({get_confidence_level(cls_conf)})")
262
 
263
+ # Enhanced Segmentation confidence section with detailed explanations
264
+ st.write("\nπŸ” **Understanding Segmentation Confidence:**")
265
+ st.write("""
266
+ Segmentation confidence shows how certain the AI is about each pixel it classified:
267
+ β€’ For the Optic Cup (central depression):
268
+ - Measures the AI's certainty that the red-colored pixels are truly part of the cup
269
+ - Higher confidence means clearer cup boundaries and more reliable VCDR
270
+
271
+ β€’ For the Optic Disc (entire circular area):
272
+ - Indicates how sure the AI is about the green-outlined disc boundary
273
+ - Higher confidence suggests better disc margin visibility
274
+
275
+ Confidence scores are calculated by averaging the model's certainty
276
+ for each pixel it identified as cup or disc. A score of 100% would mean
277
+ the model is absolutely certain about every pixel's classification.
278
+ """)
279
+
280
+ st.write("\nπŸ“Š **Current Segmentation Confidence Scores:**")
281
  st.write(f"β€’ Optic Cup Detection: {cup_conf:.1f}% - {get_confidence_level(cup_conf)}")
282
  st.write(f"β€’ Optic Disc Detection: {disc_conf:.1f}% - {get_confidence_level(disc_conf)}")
283
 
284
+ # Add interpretation guidance
285
+ if cup_conf >= 75 and disc_conf >= 75:
286
+ st.write("βœ… High confidence scores indicate reliable measurements")
287
+ elif cup_conf < 60 or disc_conf < 60:
288
+ st.write("""
289
+ ⚠️ Lower confidence scores might be due to:
290
+ β€’ Image quality issues (blur, poor contrast)
291
+ β€’ Unusual anatomical variations
292
+ β€’ Pathological changes affecting visibility
293
+ β€’ Poor image centering or focus
294
+
295
+ Consider retaking the image if possible.
296
+ """)
297
+
298
  # Clinical metrics
299
  st.write("\nπŸ“ **Clinical Measurements:**")
300
  st.write(f"β€’ Cup-to-Disc Ratio (VCDR): {vcdr:.3f}")