ProjetRaoul/app.py

308 lines
15 KiB
Python
Raw Normal View History

2024-04-20 20:54:53 +00:00
#!/usr/bin/env python
# coding: utf-8
# In[2]:
import streamlit as st
from PIL import Image
import numpy as np
import os
import pydicom as dicom
import io
import matplotlib.pyplot as plt
from Segment_Stack_without_gpu import SegBScan, SegShrinkBScan
# In[7]:
st.set_page_config(layout="wide")
def main():
selected_box = st.sidebar.selectbox(
'Choose one of the following',
('Welcome','LC-OCT image analysis')
)
if selected_box == 'Welcome':
welcome()
if selected_box == 'LC-OCT image analysis':
#selected_radio = st.sidebar.radio("Select analysis:", ["Visualisation", "Segmentation"])
#if selected_radio == "Visualisation":
lcoct()
def welcome():
st.title('3D Stack LCOCT images Visualisation and Processing')
st.subheader("This app is designed to swiftly visualize and analyze LCOCT images, specifically focusing on segmentation."
+ " The application is currently in deployment, and additional tools will be incorporated in the future.")
st.image('LCOCT_Stack.png',use_column_width=True)
def lcoct():
st.title('Visualisation')
allowed_extensions = ["dcm"]
uploaded_files = st.file_uploader("Choose LCOCT files", type=allowed_extensions, accept_multiple_files=True)
#file_contents = uploaded_file.read()
# Display the contents
count = 0
if uploaded_files:
st.text("Uploaded LCOCT data:")
for i, file in enumerate(uploaded_files):
file_size = len(file.read())
#if (file_size//1024)>2000 :
st.text(f"{i}, {file.name}")
count+=1
#st.text(file_size)
if uploaded_files:
stack = st.slider('Which stack do you whant to visualize?', 0, count, 0)
st.write("Current Selected Stack: ", stack)
if uploaded_files:
selected_file = uploaded_files[stack]
data = dicom.dcmread(io.BytesIO(selected_file.getvalue())).pixel_array
if data.ndim == 3 :
data = data
else :
data = np.transpose(data[np.newaxis,...], (1,0,2))
selected_slice = st.slider("Select Slice", 0, data.shape[1] - 1, 0)
selected_image_slice = data[:, selected_slice, :]
st.image(selected_image_slice, caption=f"Slice {selected_slice}", use_column_width=True)
save_directory1 = st.text_input("Enter the download directory path:", key="file_uploader1")
# Button to save the current slice
if st.button("Save Slice", key="save_button1"):
#save_directory1 = st.file_uploader("Choose a directory to save the slice", type=["directory"], key="file_uploader1")
# Check if the directory is selected
if save_directory1 is not None:
# Get the selected directory path
directory_path = os.path.abspath(save_directory1)
# Create the directory if it doesn't exist
os.makedirs(directory_path, exist_ok=True)
# Save the slice as an image using matplotlib with a custom filename and selected directory
filename = f"dicom_slice_{selected_slice}.png"
full_path = os.path.join(directory_path, filename)
plt.imsave(full_path, selected_image_slice, cmap='gray')
st.success(f"Slice {selected_slice} saved successfully.")
else:
st.warning("Please choose a directory to save the image.")
#if st.button("Save Slice"):
# plt.imsave(f"lcoct_slice_{selected_slice}.png", selected_image_slice, cmap='gray')
# st.success(f"Slice {selected_slice} saved successfully.")
if uploaded_files:
selected_file = uploaded_files[stack]
data = dicom.dcmread(io.BytesIO(selected_file.getvalue())).pixel_array
if data.ndim == 3 :
data = data
else :
data = np.transpose(data[np.newaxis,...], (1,0,2))
selected_slice = st.slider("Select Slice", 0, data.shape[0] - 1, 0)
selected_image_slice = data[selected_slice, :, :]
st.image(selected_image_slice, caption=f"Slice {selected_slice}", use_column_width=True)
#save_directory2 = st.file_uploader("Choose a directory to save the slice", type=["directory"], key="file_uploader2")
save_directory2 = st.text_input("Enter the download directory path:", key="file_uploader2")
# Button to save the current slice
if st.button("Save Slice", key="save_button2"):
# Check if the directory is selected
if save_directory2 is not None:
# Get the selected directory path
directory_path = os.path.abspath(save_directory2)
# Create the directory if it doesn't exist
os.makedirs(directory_path, exist_ok=True)
# Save the slice as an image using matplotlib with a custom filename and selected directory
filename = f"dicom_slice_{selected_slice}.png"
full_path = os.path.join(directory_path, filename)
plt.imsave(full_path, selected_image_slice, cmap='gray')
st.success(f"Slice {selected_slice} saved successfully.")
else:
st.warning("Please choose a directory to save the image.")
if uploaded_files:
selected_file = uploaded_files[stack]
data = dicom.dcmread(io.BytesIO(selected_file.getvalue())).pixel_array
if data.ndim == 3 :
data = data
else :
data = np.transpose(data[np.newaxis,...], (1,0,2))
selected_slice = st.slider("Select Slice", 0, data.shape[2] - 1, 0)
selected_image_slice = data[:, :, selected_slice]
st.image(selected_image_slice, caption=f"Slice {selected_slice}", use_column_width=True)
#save_directory3 = st.file_uploader("Choose a directory to save the slice", type=["directory"], key="file_uploader3")
save_directory3 = st.text_input("Enter the download directory path:", key="file_uploader3")
# Button to save the current slice
if st.button("Save Slice", key="save_button3"):
# Check if the directory is selected
if save_directory3 is not None:
# Get the selected directory path
directory_path = os.path.abspath(save_directory3)
# Create the directory if it doesn't exist
os.makedirs(directory_path, exist_ok=True)
# Save the slice as an image using matplotlib with a custom filename and selected directory
filename = f"dicom_slice_{selected_slice}.png"
full_path = os.path.join(directory_path, filename)
plt.imsave(full_path, selected_image_slice, cmap='gray')
st.success(f"Slice {selected_slice} saved successfully.")
else:
st.warning("Please choose a directory to save the image.")
##################################Segmentation########################################
st.title('Segmentation of Stratum Corneum')
st.write("This will take a few minitues ")
@st.cache_data
def segmentation(data1, remove1, disk1) :
#if uploaded_files:
result = SegBScan(data1, remove_num=remove1, disk_num=disk1)
contours1, denoised_med1, epaiss1 = result.return_im_cont()
epaiss1mean = result.sc_shrink()
epaiss1std = result.image_std()
return contours1, denoised_med1, epaiss1, epaiss1mean, epaiss1std
@st.cache_data
def segmentation1(data2, remove2, disk2):
#if uploaded_files:
result2 = SegShrinkBScan(data2, remove_num=remove2, disk_num=disk2)
contours2, denoised_med2, epaiss2 = result2.return_im_cont()
epaiss2mean = result2.sc_shrink()
epaiss2std = result2.image_std()
return contours2, denoised_med2, epaiss2, epaiss2mean, epaiss2std
@st.cache_data
def segmentation2(data1, disk1, disk2, octagon1, octagon2) :
#if uploaded_files:
result = SegBScan(data1, disk_num1 = disk1, disk_num2 = disk2, octagon_num1 = octagon1, octagon_num2 = octagon2)
contours1, denoised_med1, epaiss1 = result.return_im_cont()
epaiss1mean = result.sc_shrink()
epaiss1std = result.image_std()
return contours1, denoised_med1, epaiss1, epaiss1mean, epaiss1std
@st.cache_data
def segmentation3(data2, disk1, disk2, octagon1, octagon2):
#if uploaded_files:
result2 = SegShrinkBScan(data2, disk_num1 = disk1, disk_num2 = disk2, octagon_num1 = octagon1, octagon_num2 = octagon2)
contours2, denoised_med2, epaiss2 = result2.return_im_cont()
epaiss2mean = result2.sc_shrink()
epaiss2std = result2.image_std()
return contours2, denoised_med2, epaiss2, epaiss2mean, epaiss2std
selected_box = st.sidebar.selectbox(
'Choose one of the following postprocessing',
('1st way','2nd way')
)
if selected_box == '2nd way':
st.text("This postprocessing uses morphology.remove_small_objects followed by morphology.dilatation")
if uploaded_files:
selected_remove = st.slider("Select the smallest allowable object size. Choosing a value will rerun the whole segmentation", 0, 500, 50, key='remove')
selected_disk = st.slider("Select the radius of the disk-shaped footprint. Choosing a value will rerun the whole segmentation", 0, 10, 3, key='disk')
contours, denoised_med, epaiss, epaiss_mean, epaiss_std = segmentation(data,selected_remove, selected_disk)
denoised_med_get = denoised_med.copy()
selected_slice = st.slider("Select Slice", 0, denoised_med.shape[1] - 1, 0)
selected_image_slice = denoised_med_get[:, selected_slice,:]
#st.image(selected_image_slice, caption=f"Slice {selected_slice}", use_column_width=True)
fig, ax = plt.subplots()
ax.imshow(selected_image_slice, cmap='gray')
ax.set_title(f"Slice N°{selected_slice} ; Epaisseur du Stratum Corneum : {np.round(epaiss[selected_slice],3)}µm, (Epaisseur du stack {np.round(epaiss_mean,3)}µm +/- {np.round(epaiss_std,3)})", fontsize=6)
ax.axis('off')
for i in contours[selected_slice] :
if (len(i)> 200):
ax.plot(i[:,1],i[:,0])
st.pyplot(fig)
if uploaded_files:
selected_remove = st.slider("Select the smallest allowable object size. Choosing a value will rerun the whole segmentation", 0, 500, 50, key='remove2')
selected_disk = st.slider("Select the radius of the disk-shaped footprint. Choosing a value will rerun the whole segmentation", 0, 10, 2, key='disk2')
contours1, denoised_med1, epaiss1, epaiss_mean1, epaiss_std1 = segmentation1(data, selected_remove, selected_disk)
denoised_med_get1 = denoised_med1.copy()
selected_slice = st.slider("Select Slice", 0, denoised_med1.shape[2] - 1, 0, key =6)
selected_image_slice = denoised_med_get1[:, :,selected_slice]
#st.image(selected_image_slice, caption=f"Slice {selected_slice}", use_column_width=True)
fig, ax = plt.subplots()
ax.imshow(selected_image_slice, cmap='gray')
ax.set_title(f"Slice N°{selected_slice} ; Epaisseur du Stratum Corneum : {np.round(epaiss1[selected_slice],3)}µm, (Epaisseur du stack {np.round(epaiss_mean1,3)}µm +/- {np.round(epaiss_std1,3)})", fontsize=6)
ax.axis('off')
for i in contours1[selected_slice] :
if (len(i)> 200):
ax.plot(i[:,1],i[:,0])
st.pyplot(fig)
if selected_box == '1st way':
st.text("This postprocessing uses morphology.erosion followed by dilation and binary.closing")
if uploaded_files:
selected_disk11 = st.slider("Select the radius of the disk-shaped footprint. Choosing a value will rerun the whole segmentation", 0, 10, 3, key='disk11')
selected_disk12 = st.slider("Select the radius of the disk-shaped footprint. Choosing a value will rerun the whole segmentation", 0, 20, 0, key='disk12')
st.text("Generates an octagon shaped footprint")
selected_octagon1 = st.slider("The size of the horizontal and vertical sides. Choosing a value will rerun the whole segmentation", 0, 5, 0, key='octagon1')
selected_octagon2 = st.slider("The height or width of the slanted sides. Choosing a value will rerun the whole segmentation", 0, 5, 1, key='octagon2')
contours, denoised_med, epaiss, epaiss_mean, epaiss_std = segmentation2(data,selected_disk11, selected_disk12, selected_octagon1, selected_octagon2)
denoised_med_get = denoised_med.copy()
selected_slice = st.slider("Select Slice", 0, denoised_med.shape[1] - 1, 0)
selected_image_slice = denoised_med_get[:, selected_slice,:]
#st.image(selected_image_slice, caption=f"Slice {selected_slice}", use_column_width=True)
fig, ax = plt.subplots()
ax.imshow(selected_image_slice, cmap='gray')
ax.set_title(f"Slice N°{selected_slice} ; Epaisseur du Stratum Corneum : {np.round(epaiss[selected_slice],3)}µm, (Epaisseur du stack {np.round(epaiss_mean,3)}µm +/- {np.round(epaiss_std,3)})", fontsize=6)
ax.axis('off')
for i in contours[selected_slice] :
if (len(i)> 500):
ax.plot(i[:,1],i[:,0])
st.pyplot(fig)
if uploaded_files:
selected_disk11 = st.slider("Select the radius of the disk-shaped footprint. Choosing a value will rerun the whole segmentation", 0, 10, 3, key='disk13')
selected_disk12 = st.slider("Select the radius of the disk-shaped footprint. Choosing a value will rerun the whole segmentation", 0, 20, 0, key='disk14')
st.text("Generates an octagon shaped footprint")
selected_octagon1 = st.slider("The size of the horizontal and vertical sides. Choosing a value will rerun the whole segmentation", 0, 5, 0, key='octagon3')
selected_octagon2 = st.slider("The height or width of the slanted sides. Choosing a value will rerun the whole segmentation", 0, 5, 1, key='octagon4')
contours1, denoised_med1, epaiss1, epaiss_mean1, epaiss_std1 = segmentation3(data,selected_disk11, selected_disk12, selected_octagon1, selected_octagon2)
denoised_med_get1 = denoised_med1.copy()
selected_slice = st.slider("Select Slice", 0, denoised_med1.shape[2] - 1, 0, key =6)
selected_image_slice = denoised_med_get1[:, :,selected_slice]
#st.image(selected_image_slice, caption=f"Slice {selected_slice}", use_column_width=True)
fig, ax = plt.subplots()
ax.imshow(selected_image_slice, cmap='gray')
ax.set_title(f"Slice N°{selected_slice} ; Epaisseur du Stratum Corneum : {np.round(epaiss1[selected_slice],3)}µm, (Epaisseur du stack {np.round(epaiss_mean1,3)}µm +/- {np.round(epaiss_std1,3)})", fontsize=6)
ax.axis('off')
for i in contours1[selected_slice] :
if (len(i)> 200):
ax.plot(i[:,1],i[:,0])
st.pyplot(fig)
if __name__ == "__main__":
main()