luigi12345
commited on
Commit
•
0eb72c7
1
Parent(s):
7a986e7
Update app.py
Browse files
app.py
CHANGED
@@ -57,12 +57,67 @@ class GlaucomaModel(object):
|
|
57 |
image_shape = image.shape[:2]
|
58 |
disease_idx, cls_confidence = self.glaucoma_pred(image)
|
59 |
disc_cup, cup_confidence, disc_confidence = self.optic_disc_cup_pred(image)
|
|
|
60 |
try:
|
61 |
-
vcdr = simple_vcdr(disc_cup) #
|
62 |
except:
|
63 |
vcdr = np.nan
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
_, disc_cup_image = add_mask(image, disc_cup, [1, 2], [[0, 255, 0], [255, 0, 0]], 0.2)
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
# --- Streamlit Interface ---
|
68 |
def main():
|
@@ -73,10 +128,11 @@ def main():
|
|
73 |
st.write('Developed by X. Sun. Find more info about me: https://pamixsun.github.io')
|
74 |
|
75 |
# Set columns for the interface
|
76 |
-
cols = st.beta_columns((1, 1, 1))
|
77 |
cols[0].subheader("Input image")
|
78 |
cols[1].subheader("Optic disc and optic cup")
|
79 |
-
cols[2].subheader("
|
|
|
80 |
|
81 |
# File uploader
|
82 |
st.sidebar.title("Image selection")
|
@@ -103,7 +159,7 @@ def main():
|
|
103 |
|
104 |
with st.spinner('Analyzing...'):
|
105 |
# Get predictions from the model
|
106 |
-
disease_idx, disc_cup_image, vcdr, cls_confidence, cup_confidence, disc_confidence = model.process(image)
|
107 |
|
108 |
# Display optic disc and cup image
|
109 |
ax.imshow(disc_cup_image)
|
@@ -115,6 +171,11 @@ def main():
|
|
115 |
ax.axis('off')
|
116 |
cols[2].pyplot(fig)
|
117 |
|
|
|
|
|
|
|
|
|
|
|
118 |
# Display results with confidence
|
119 |
st.subheader("Screening results:")
|
120 |
final_results_as_table = f"""
|
|
|
57 |
image_shape = image.shape[:2]
|
58 |
disease_idx, cls_confidence = self.glaucoma_pred(image)
|
59 |
disc_cup, cup_confidence, disc_confidence = self.optic_disc_cup_pred(image)
|
60 |
+
|
61 |
try:
|
62 |
+
vcdr = simple_vcdr(disc_cup) # Calculate vertical cup-to-disc ratio
|
63 |
except:
|
64 |
vcdr = np.nan
|
65 |
+
|
66 |
+
# Mask for optic disc and cup
|
67 |
+
mask = (disc_cup > 0).astype(np.uint8)
|
68 |
+
|
69 |
+
# Get bounding box of the optic cup + disc and add padding
|
70 |
+
x, y, w, h = cv2.boundingRect(mask)
|
71 |
+
padding = 20 # Add padding to avoid edge distortion
|
72 |
+
x = max(x - padding, 0)
|
73 |
+
y = max(y - padding, 0)
|
74 |
+
w = min(w + 2 * padding, image.shape[1] - x)
|
75 |
+
h = min(h + 2 * padding, image.shape[0] - y)
|
76 |
+
|
77 |
+
# Ensure that the bounding box is large enough to avoid cropping errors
|
78 |
+
min_size = 50 # Define a minimum size for the cropped image
|
79 |
+
if w < min_size or h < min_size:
|
80 |
+
cropped_image = image.copy() # Fallback: if bounding box too small, return original image
|
81 |
+
else:
|
82 |
+
cropped_image = image[y:y+h, x:x+w]
|
83 |
+
|
84 |
+
# Generate disc and cup visualization
|
85 |
_, disc_cup_image = add_mask(image, disc_cup, [1, 2], [[0, 255, 0], [255, 0, 0]], 0.2)
|
86 |
+
|
87 |
+
return disease_idx, disc_cup_image, vcdr, cls_confidence, cup_confidence, disc_confidence, cropped_image
|
88 |
+
|
89 |
+
# --- Utility Functions ---
|
90 |
+
def simple_vcdr(mask):
|
91 |
+
"""
|
92 |
+
Simple function to calculate the vertical cup-to-disc ratio (VCDR).
|
93 |
+
Assumes:
|
94 |
+
- mask contains class 1 for optic disc and class 2 for optic cup.
|
95 |
+
"""
|
96 |
+
disc_area = np.sum(mask == 1)
|
97 |
+
cup_area = np.sum(mask == 2)
|
98 |
+
|
99 |
+
# Avoid division by zero
|
100 |
+
if disc_area == 0:
|
101 |
+
return np.nan
|
102 |
+
vcdr = cup_area / disc_area
|
103 |
+
return vcdr
|
104 |
+
|
105 |
+
def add_mask(image, mask, classes, colors, alpha=0.5):
|
106 |
+
"""
|
107 |
+
Adds a transparent mask to the original image.
|
108 |
+
Args:
|
109 |
+
- image: the original RGB image
|
110 |
+
- mask: the predicted segmentation mask
|
111 |
+
- classes: a list of class indices to apply masks for (e.g., [1, 2])
|
112 |
+
- colors: a list of colors for each class (e.g., [[0, 255, 0], [255, 0, 0]] for green and red)
|
113 |
+
- alpha: transparency level (default = 0.5)
|
114 |
+
"""
|
115 |
+
overlay = image.copy()
|
116 |
+
for class_id, color in zip(classes, colors):
|
117 |
+
overlay[mask == class_id] = color
|
118 |
+
# Blend the overlay with the original image
|
119 |
+
output = cv2.addWeighted(overlay, alpha, image, 1 - alpha, 0)
|
120 |
+
return output, overlay
|
121 |
|
122 |
# --- Streamlit Interface ---
|
123 |
def main():
|
|
|
128 |
st.write('Developed by X. Sun. Find more info about me: https://pamixsun.github.io')
|
129 |
|
130 |
# Set columns for the interface
|
131 |
+
cols = st.beta_columns((1, 1, 1, 1))
|
132 |
cols[0].subheader("Input image")
|
133 |
cols[1].subheader("Optic disc and optic cup")
|
134 |
+
cols[2].subheader("Class activation map")
|
135 |
+
cols[3].subheader("Cropped Image")
|
136 |
|
137 |
# File uploader
|
138 |
st.sidebar.title("Image selection")
|
|
|
159 |
|
160 |
with st.spinner('Analyzing...'):
|
161 |
# Get predictions from the model
|
162 |
+
disease_idx, disc_cup_image, vcdr, cls_confidence, cup_confidence, disc_confidence, cropped_image = model.process(image)
|
163 |
|
164 |
# Display optic disc and cup image
|
165 |
ax.imshow(disc_cup_image)
|
|
|
171 |
ax.axis('off')
|
172 |
cols[2].pyplot(fig)
|
173 |
|
174 |
+
# Display the cropped image
|
175 |
+
ax.imshow(cropped_image)
|
176 |
+
ax.axis('off')
|
177 |
+
cols[3].pyplot(fig)
|
178 |
+
|
179 |
# Display results with confidence
|
180 |
st.subheader("Screening results:")
|
181 |
final_results_as_table = f"""
|