luigi12345
commited on
Commit
β’
c4921c6
1
Parent(s):
56a1577
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=
|
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 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
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 (
|
108 |
elif confidence >= 75:
|
109 |
-
return "Good (
|
110 |
elif confidence >= 60:
|
111 |
-
return "Fair (
|
112 |
elif confidence >= 45:
|
113 |
-
return "Poor (
|
114 |
else:
|
115 |
-
return "Very Poor (
|
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 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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}")
|