FatemehT commited on
Commit
a8ab7ac
·
1 Parent(s): b5cbaa6

fix the build

Browse files
.DS_Store ADDED
Binary file (6.15 kB). View file
 
__pycache__/angioPyFunctions.cpython-313.pyc ADDED
Binary file (10.8 kB). View file
 
__pycache__/angioPySegmentation.cpython-313.pyc ADDED
Binary file (13.8 kB). View file
 
__pycache__/predict.cpython-313.pyc ADDED
Binary file (2.9 kB). View file
 
angioPyFunctions.py CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
  import numpy
2
  import scipy.interpolate
3
  import skimage.filters
@@ -6,6 +9,13 @@ import scipy.ndimage
6
  import scipy.optimize
7
  import predict
8
  from PIL import Image
 
 
 
 
 
 
 
9
  from fil_finder import FilFinder2D
10
  import astropy.units as u
11
  from tqdm import tqdm
 
1
+ import os
2
+ os.environ.setdefault("ASTROPY_SKIP_CONFIG_UPDATE", "1")
3
+
4
  import numpy
5
  import scipy.interpolate
6
  import skimage.filters
 
9
  import scipy.optimize
10
  import predict
11
  from PIL import Image
12
+ import astropy.config.configuration as _astro_config
13
+
14
+ if not hasattr(_astro_config, "update_default_config"):
15
+ def _noop_update_default_config(*args, **kwargs):
16
+ return None
17
+ _astro_config.update_default_config = _noop_update_default_config
18
+
19
  from fil_finder import FilFinder2D
20
  import astropy.units as u
21
  from tqdm import tqdm
angioPySegmentation.py CHANGED
@@ -77,7 +77,6 @@ files = sorted(glob.glob(DicomFolder+"/*"))
77
  for file in files:
78
  exampleDicoms[os.path.basename(file)] = file
79
 
80
-
81
  # Main text
82
  st.markdown("<h1 style='text-align: center;'>AngioPy Segmentation</h1>", unsafe_allow_html=True)
83
  st.markdown("<h5 style='text-align: center;'> Welcome to <b>AngioPy Segmentation</b>, an AI-driven, coronary angiography segmentation tool.</h1>", unsafe_allow_html=True)
@@ -93,14 +92,62 @@ st.markdown("")
93
 
94
  # print("CHANGED!")
95
 
 
 
 
 
 
96
 
97
- DropDownDicom = st.sidebar.selectbox("Select example DICOM file:",
98
- options = list(exampleDicoms.keys()),
99
- # on_change=changeSessionState(st.session_state.key),
100
- key="dicomDropDown"
101
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
- selectedDicom = exampleDicoms[DropDownDicom]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  stepOne = st.sidebar.expander("STEP ONE", True)
106
  stepTwo = st.sidebar.expander("STEP TWO", True)
@@ -121,34 +168,24 @@ st.markdown(css, unsafe_allow_html=True)
121
 
122
  # while True:
123
  # Once a file is uploaded, the following annotation sequence is initiated
124
- if selectedDicom is not None:
125
- try:
126
- print(f"Trying to load {selectedDicom}")
127
- dcm = pydicom.dcmread(selectedDicom, force=True)
128
-
129
- # handAngle = dcm.PositionerPrimaryAngle
130
- # headAngle = dcm.PositionerSecondaryAngle
131
- # dcmLabel = f"{'LAO' if handAngle > 0 else 'RAO'} {numpy.abs(handAngle):04.1f}° {'CRA' if headAngle > 0 else 'CAU'} {numpy.abs(headAngle):04.1f}°"
132
 
133
- pixelArray = dcm.pixel_array
134
-
135
- # Just take first channel if it's RGB?
136
- if len(pixelArray.shape) == 4:
137
- pixelArray = pixelArray[:,:,:,0]
138
-
139
- n_slices = pixelArray.shape[0]
140
-
141
- slice_ix = 0
142
- except:
143
- selectedDicom = None
144
- # continue
145
 
146
  with tab1:
147
 
148
  with stepOne:
149
  st.write("Select frame for annotation. Aim for an end-diastolic frame with good visualisation of the artery of interest.")
150
 
151
- slice_ix = st.slider('Frame', 0, n_slices-1, int(n_slices/2), key='sliceSlider')
 
152
 
153
 
154
  predictedMask = numpy.zeros_like(pixelArray[slice_ix, :, :])
@@ -183,6 +220,8 @@ if selectedDicom is not None:
183
  selectedFrame = pixelArray[slice_ix, :, :]
184
  selectedFrame = cv2.resize(selectedFrame, (512,512))
185
 
 
 
186
  # Create a canvas component
187
  annotationCanvas = st_canvas(
188
  fill_color="red", # Fixed fill color with some opacity
@@ -195,11 +234,12 @@ if selectedDicom is not None:
195
  width=512,
196
  drawing_mode="point",
197
  point_display_radius=2,
198
- key=st.session_state.dicomDropDown,
199
  )
200
 
201
 
202
  # Do something interesting with the image data and paths
 
203
  if annotationCanvas.json_data is not None:
204
  objects = pd.json_normalize(annotationCanvas.json_data["objects"]) # need to convert obj to str because PyArrow
205
 
@@ -222,7 +262,6 @@ if selectedDicom is not None:
222
  predictedMask = predict.CoronaryDataset.mask2image(mask)
223
  # predictedMask = predictedMask.crop((0, 0, imageSize[0], imageSize[1]))
224
  predictedMask = numpy.asarray(predictedMask)
225
-
226
  with col2:
227
  col2a, col2b, col2c = st.columns((1,10,1))
228
 
 
77
  for file in files:
78
  exampleDicoms[os.path.basename(file)] = file
79
 
 
80
  # Main text
81
  st.markdown("<h1 style='text-align: center;'>AngioPy Segmentation</h1>", unsafe_allow_html=True)
82
  st.markdown("<h5 style='text-align: center;'> Welcome to <b>AngioPy Segmentation</b>, an AI-driven, coronary angiography segmentation tool.</h1>", unsafe_allow_html=True)
 
92
 
93
  # print("CHANGED!")
94
 
95
+ input_mode = st.sidebar.radio(
96
+ "Input source",
97
+ ("Example DICOM", "Upload Image"),
98
+ key="input_mode_selector",
99
+ )
100
 
101
+ pixelArray = None
102
+ selected_label = None
103
+ selected_path = None
104
+
105
+ if input_mode == "Example DICOM":
106
+ if exampleDicoms:
107
+ DropDownDicom = st.sidebar.selectbox(
108
+ "Select example DICOM file:",
109
+ options=list(exampleDicoms.keys()),
110
+ key="dicomDropDown",
111
+ )
112
+
113
+ selected_label = DropDownDicom
114
+ selected_path = exampleDicoms[DropDownDicom]
115
+
116
+ try:
117
+ print(f"Trying to load {selected_path}")
118
+ dcm = pydicom.dcmread(selected_path, force=True)
119
 
120
+ pixelArray = dcm.pixel_array
121
+
122
+ # Just take first channel if it's RGB?
123
+ if len(pixelArray.shape) == 4:
124
+ pixelArray = pixelArray[:, :, :, 0]
125
+ except Exception as err:
126
+ st.sidebar.error(f"Unable to read DICOM '{selected_label}': {err}")
127
+ pixelArray = None
128
+ else:
129
+ st.sidebar.info("Add DICOM files to the `Dicoms/` folder or switch to image upload.")
130
+ else:
131
+ uploaded_file = st.sidebar.file_uploader(
132
+ "Upload angiography frame (PNG or JPG)",
133
+ type=["png", "jpg", "jpeg"],
134
+ key="uploaded_frame",
135
+ )
136
+
137
+ if uploaded_file is not None:
138
+ selected_label = uploaded_file.name
139
+ selected_path = uploaded_file.name
140
+
141
+ try:
142
+ uploaded_image = Image.open(uploaded_file)
143
+ if uploaded_image.mode != "L":
144
+ uploaded_image = uploaded_image.convert("L")
145
+
146
+ image_array = numpy.array(uploaded_image)
147
+ pixelArray = numpy.expand_dims(image_array, axis=0)
148
+ except Exception as err:
149
+ st.sidebar.error(f"Could not read uploaded image: {err}")
150
+ pixelArray = None
151
 
152
  stepOne = st.sidebar.expander("STEP ONE", True)
153
  stepTwo = st.sidebar.expander("STEP TWO", True)
 
168
 
169
  # while True:
170
  # Once a file is uploaded, the following annotation sequence is initiated
171
+ if pixelArray is None:
172
+ st.info("Select an example DICOM or upload a PNG/JPG frame to start the segmentation workflow.")
173
+ else:
174
+ if pixelArray.ndim == 4:
175
+ pixelArray = pixelArray[:, :, :, 0]
176
+ if pixelArray.ndim == 2:
177
+ pixelArray = numpy.expand_dims(pixelArray, axis=0)
 
178
 
179
+ n_slices = pixelArray.shape[0]
180
+ slice_ix = 0
 
 
 
 
 
 
 
 
 
 
181
 
182
  with tab1:
183
 
184
  with stepOne:
185
  st.write("Select frame for annotation. Aim for an end-diastolic frame with good visualisation of the artery of interest.")
186
 
187
+ if n_slices > 1:
188
+ slice_ix = st.slider('Frame', 0, n_slices-1, int(n_slices/2), key='sliceSlider')
189
 
190
 
191
  predictedMask = numpy.zeros_like(pixelArray[slice_ix, :, :])
 
220
  selectedFrame = pixelArray[slice_ix, :, :]
221
  selectedFrame = cv2.resize(selectedFrame, (512,512))
222
 
223
+ canvas_key = f"canvas-{selected_label}" if selected_label else "canvas-default"
224
+
225
  # Create a canvas component
226
  annotationCanvas = st_canvas(
227
  fill_color="red", # Fixed fill color with some opacity
 
234
  width=512,
235
  drawing_mode="point",
236
  point_display_radius=2,
237
+ key=canvas_key,
238
  )
239
 
240
 
241
  # Do something interesting with the image data and paths
242
+ objects = pd.DataFrame()
243
  if annotationCanvas.json_data is not None:
244
  objects = pd.json_normalize(annotationCanvas.json_data["objects"]) # need to convert obj to str because PyArrow
245
 
 
262
  predictedMask = predict.CoronaryDataset.mask2image(mask)
263
  # predictedMask = predictedMask.crop((0, 0, imageSize[0], imageSize[1]))
264
  predictedMask = numpy.asarray(predictedMask)
 
265
  with col2:
266
  col2a, col2b, col2c = st.columns((1,10,1))
267
 
normalize_k1.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ import numpy as np
4
+ from PIL import Image
5
+ from skimage import exposure
6
+
7
+
8
+ def normalize_image(
9
+ src: Path,
10
+ dst: Path,
11
+ target_size=(512, 512),
12
+ png_low: int = 16,
13
+ png_high: int = 238,
14
+ ) -> None:
15
+ """Convert JPEG to grayscale, resize, and match PNG intensity distribution."""
16
+ img = Image.open(src).convert("L")
17
+ img = img.resize(target_size, Image.Resampling.BICUBIC)
18
+
19
+ arr = np.array(img, dtype=np.float32)
20
+ arr = exposure.rescale_intensity(arr, in_range="image", out_range=(png_low, png_high))
21
+ arr = np.clip(arr, png_low, png_high)
22
+ arr = ((arr - png_low) / (png_high - png_low) * 255.0).astype(np.uint8)
23
+
24
+ dst.parent.mkdir(parents=True, exist_ok=True)
25
+ Image.fromarray(arr, mode="L").save(dst)
26
+
27
+
28
+ if __name__ == "__main__":
29
+ src = Path("/Users/fatemehtahavori/Downloads/atk1/K-1.jpg")
30
+ dst = Path("normalized_outputs") / f"{src.stem}_normalized.png"
31
+
32
+ normalize_image(src, dst)
33
+ print(f"Saved normalized frame to {dst.resolve()}")
requirements.txt CHANGED
@@ -1,29 +1,29 @@
1
  # Automatically generated by https://github.com/damnever/pigar.
2
 
3
- astropy==5.2.2
4
  efficientnet-pytorch==0.7.1
5
  fil-finder==1.7.2
6
- matplotlib==3.7.2
7
  mpld3==0.5.9
8
- numpy==1.24.4
9
- opencv-python==4.8.0.76
10
- pandas==2.0.3
11
- Pillow==9.5.0
12
  plotly==5.16.1
13
  pretrainedmodels==0.7.4
14
  pydicom==2.4.3
15
- PyYAML==6.0.1
16
- scikit-image==0.21.0
17
- scikit-learn==1.3.0
18
- scipy==1.10.1
19
- setuptools==47.1.0
20
- SimpleITK==2.2.1
21
  streamlit<=1.38.0
22
  streamlit-drawable-canvas==0.9.3
23
  streamlit-plotly-events==0.0.6
24
- tifffile==2023.7.10
25
- timm==0.9.6
26
- torch==2.0.1
27
- torchvision==0.15.2
28
- tqdm==4.61.1
29
  pooch
 
1
  # Automatically generated by https://github.com/damnever/pigar.
2
 
3
+ astropy>=7.0.0
4
  efficientnet-pytorch==0.7.1
5
  fil-finder==1.7.2
6
+ matplotlib>=3.10.0
7
  mpld3==0.5.9
8
+ numpy>=2.0.0
9
+ opencv-python>=4.10.0
10
+ pandas>=2.3.0
11
+ Pillow>=10.0.0
12
  plotly==5.16.1
13
  pretrainedmodels==0.7.4
14
  pydicom==2.4.3
15
+ PyYAML>=6.0.1
16
+ scikit-image>=0.25.0
17
+ scikit-learn>=1.7.0
18
+ scipy>=1.16.0
19
+ setuptools>=65.0.0
20
+ SimpleITK>=2.5.2
21
  streamlit<=1.38.0
22
  streamlit-drawable-canvas==0.9.3
23
  streamlit-plotly-events==0.0.6
24
+ tifffile>=2023.7.10
25
+ timm>=0.9.6
26
+ torch>=2.8.0
27
+ torchvision>=0.23.0
28
+ tqdm>=4.61.1
29
  pooch
utils/__pycache__/augment.cpython-313.pyc ADDED
Binary file (8.96 kB). View file
 
utils/__pycache__/dataset.cpython-313.pyc ADDED
Binary file (17 kB). View file
 
utils/__pycache__/utils.cpython-313.pyc ADDED
Binary file (4.8 kB). View file