Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -4,10 +4,6 @@ from PIL import Image
|
|
4 |
import os
|
5 |
from typing import Tuple, Optional
|
6 |
import logging
|
7 |
-
import numpy as np
|
8 |
-
from skimage import filters, morphology, measure, segmentation, color
|
9 |
-
import matplotlib.pyplot as plt
|
10 |
-
from io import BytesIO
|
11 |
|
12 |
# Configure logging
|
13 |
logging.basicConfig(level=logging.INFO)
|
@@ -115,48 +111,6 @@ Follow the structure below:
|
|
115 |
logger.error(f"Analysis failed: {str(e)}")
|
116 |
return None, None
|
117 |
|
118 |
-
def segment_image(self, img: Image.Image) -> Tuple[Optional[Image.Image], Optional[Image.Image]]:
|
119 |
-
"""
|
120 |
-
Segment the MRI scan using open-source scikit-image algorithms.
|
121 |
-
Returns a tuple of (segmentation_mask, labeled_image) if successful.
|
122 |
-
"""
|
123 |
-
try:
|
124 |
-
# Convert PIL Image to numpy array
|
125 |
-
img_array = np.array(img.convert('L')) # Convert to grayscale
|
126 |
-
|
127 |
-
# Apply threshold using Otsu's method
|
128 |
-
threshold = filters.threshold_otsu(img_array)
|
129 |
-
binary = img_array > threshold
|
130 |
-
|
131 |
-
# Clean up binary image
|
132 |
-
binary = morphology.remove_small_objects(binary, min_size=50)
|
133 |
-
binary = morphology.remove_small_holes(binary, area_threshold=50)
|
134 |
-
|
135 |
-
# Optional: Apply watershed for better segmentation
|
136 |
-
distance = morphology.distance_transform_edt(binary)
|
137 |
-
local_max = filters.rank.local_max(distance, morphology.disk(5))
|
138 |
-
markers = measure.label(local_max)
|
139 |
-
labels = segmentation.watershed(-distance, markers, mask=binary)
|
140 |
-
|
141 |
-
# Generate labeled image
|
142 |
-
label_rgb = color.label2rgb(labels, bg_label=0)
|
143 |
-
|
144 |
-
# Create contour overlay on original image
|
145 |
-
contours = segmentation.find_boundaries(labels, mode='thick')
|
146 |
-
contour_overlay = np.copy(img_array)
|
147 |
-
contour_overlay[contours] = 255
|
148 |
-
|
149 |
-
# Convert numpy arrays back to PIL Images
|
150 |
-
mask_img = Image.fromarray((binary * 255).astype(np.uint8))
|
151 |
-
label_img = Image.fromarray((label_rgb * 255).astype(np.uint8))
|
152 |
-
contour_img = Image.fromarray(contour_overlay.astype(np.uint8))
|
153 |
-
|
154 |
-
return mask_img, contour_img
|
155 |
-
|
156 |
-
except Exception as e:
|
157 |
-
logger.error(f"Segmentation failed: {str(e)}")
|
158 |
-
return None, None
|
159 |
-
|
160 |
def run(self):
|
161 |
"""Run the Streamlit MRI scan analysis application."""
|
162 |
st.title("🧠 MRI Scan Analytics")
|
@@ -171,8 +125,6 @@ Follow the structure below:
|
|
171 |
with col2:
|
172 |
if uploaded_file:
|
173 |
self.process_analysis(uploaded_file)
|
174 |
-
st.markdown("---")
|
175 |
-
self.process_segmentation(uploaded_file)
|
176 |
else:
|
177 |
self.show_instructions()
|
178 |
|
@@ -220,36 +172,6 @@ Follow the structure below:
|
|
220 |
else:
|
221 |
st.error("Analysis failed. Please try again.")
|
222 |
|
223 |
-
def process_segmentation(self, uploaded_file: object) -> None:
|
224 |
-
"""Process the uploaded MRI image and display the segmentation results."""
|
225 |
-
if st.button("🔍 Segment MRI Scan", key="segment_button"):
|
226 |
-
with st.spinner("Segmenting MRI scan using open-source algorithms..."):
|
227 |
-
img = Image.open(uploaded_file)
|
228 |
-
seg_mask, seg_contours = self.segment_image(img)
|
229 |
-
|
230 |
-
if seg_mask and seg_contours:
|
231 |
-
col1, col2 = st.columns(2)
|
232 |
-
with col1:
|
233 |
-
st.image(seg_mask, caption="Binary Segmentation Mask", use_container_width=True)
|
234 |
-
with col2:
|
235 |
-
st.image(seg_contours, caption="Region Contours", use_container_width=True)
|
236 |
-
|
237 |
-
with st.expander("Segmentation Details"):
|
238 |
-
st.markdown("""
|
239 |
-
### Segmentation Methodology
|
240 |
-
|
241 |
-
This segmentation uses a pipeline of open-source algorithms:
|
242 |
-
|
243 |
-
1. **Otsu Thresholding**: Automatically determines optimal threshold value
|
244 |
-
2. **Morphological Operations**: Removes small objects and fills holes
|
245 |
-
3. **Watershed Transform**: Separates connected regions
|
246 |
-
4. **Boundary Detection**: Identifies region boundaries
|
247 |
-
|
248 |
-
For medical diagnosis, these results should be reviewed by a qualified professional.
|
249 |
-
""")
|
250 |
-
else:
|
251 |
-
st.error("Segmentation failed. Please try again with a clearer image.")
|
252 |
-
|
253 |
@staticmethod
|
254 |
def show_instructions() -> None:
|
255 |
"""Display instructions when no image is uploaded."""
|
@@ -259,7 +181,6 @@ Follow the structure below:
|
|
259 |
st.markdown("""
|
260 |
1. *Upload* your MRI scan image.
|
261 |
2. Click *Analyze MRI Scan* to get analysis reports for medical professionals and patients.
|
262 |
-
3. Click *Segment MRI Scan* to view the segmentation results using open-source algorithms.
|
263 |
""")
|
264 |
|
265 |
@staticmethod
|
|
|
4 |
import os
|
5 |
from typing import Tuple, Optional
|
6 |
import logging
|
|
|
|
|
|
|
|
|
7 |
|
8 |
# Configure logging
|
9 |
logging.basicConfig(level=logging.INFO)
|
|
|
111 |
logger.error(f"Analysis failed: {str(e)}")
|
112 |
return None, None
|
113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
def run(self):
|
115 |
"""Run the Streamlit MRI scan analysis application."""
|
116 |
st.title("🧠 MRI Scan Analytics")
|
|
|
125 |
with col2:
|
126 |
if uploaded_file:
|
127 |
self.process_analysis(uploaded_file)
|
|
|
|
|
128 |
else:
|
129 |
self.show_instructions()
|
130 |
|
|
|
172 |
else:
|
173 |
st.error("Analysis failed. Please try again.")
|
174 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
@staticmethod
|
176 |
def show_instructions() -> None:
|
177 |
"""Display instructions when no image is uploaded."""
|
|
|
181 |
st.markdown("""
|
182 |
1. *Upload* your MRI scan image.
|
183 |
2. Click *Analyze MRI Scan* to get analysis reports for medical professionals and patients.
|
|
|
184 |
""")
|
185 |
|
186 |
@staticmethod
|