Christhofer
commited on
Commit
•
323ab6e
1
Parent(s):
a219886
additional files
Browse files- app.py +134 -11
- clasificacion.pkl +3 -0
- clasificacion_alexnet.pkl +3 -0
app.py
CHANGED
@@ -1,13 +1,136 @@
|
|
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
|
4 |
-
st.
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
import cv2
|
4 |
+
|
5 |
import streamlit as st
|
6 |
+
from streamlit_cropper import st_cropper
|
7 |
+
import tensorflow as tf
|
8 |
+
import tensorflow_io as tfio
|
9 |
+
|
10 |
+
from tensorflow import keras
|
11 |
+
|
12 |
+
import matplotlib.pyplot as plt
|
13 |
+
from PIL import Image
|
14 |
+
|
15 |
+
from fastai.vision.all import *
|
16 |
+
|
17 |
+
st.set_page_config(page_title="Aplicación cancer de mama - IXCHEN")
|
18 |
+
|
19 |
+
class Modelo:
|
20 |
+
|
21 |
+
def __init__(self, model_name):
|
22 |
+
self.model_name = model_name
|
23 |
+
self.modelo = self.cargar_modelo(self.model_name)
|
24 |
+
|
25 |
+
def cargar_modelo(self, modelo):
|
26 |
+
if modelo == "alexnet":
|
27 |
+
return load_learner('./clasificacion_alexnet.pkl')
|
28 |
+
elif modelo == 'restnet50':
|
29 |
+
return load_learner('./clasificacion.pkl')
|
30 |
+
|
31 |
+
def predecir(self, imagen):
|
32 |
+
_, _, probs = self.modelo.predict(imagen)
|
33 |
+
return probs
|
34 |
+
|
35 |
+
modelo_alexnet = Modelo('alexnet')
|
36 |
+
modelo_resnet50 = Modelo('restnet50')
|
37 |
+
|
38 |
+
realtime_update = st.sidebar.checkbox(label="Actualizar en tiempo real", value=True)
|
39 |
+
box_color = st.sidebar.color_picker(label="Color caja", value='#0000FF')
|
40 |
+
aspect_choice = st.sidebar.radio(label="Relación aspecto", options=["1:1", "16:9", "4:3", "2:3", "Free"])
|
41 |
+
aspect_dict = {
|
42 |
+
"1:1": (1, 1),
|
43 |
+
"16:9": (16, 9),
|
44 |
+
"4:3": (4, 3),
|
45 |
+
"2:3": (2, 3),
|
46 |
+
"Free": None
|
47 |
+
}
|
48 |
+
|
49 |
+
aspect_ratio = aspect_dict[aspect_choice]
|
50 |
+
class_names = ['Benigno', 'Maligno', 'Normal']
|
51 |
+
|
52 |
+
def cargar_dicom_file(image_bytes, tipo):
|
53 |
+
if tipo != 'storage':
|
54 |
+
lossy_image = tfio.image.decode_dicom_image(image_bytes.getvalue(), scale='auto', on_error='lossy', dtype=tf.uint8)
|
55 |
+
else:
|
56 |
+
lossy_image = tfio.image.decode_dicom_image(image_bytes, scale='auto', on_error='lossy', dtype=tf.uint8)
|
57 |
+
numpy_lossy_image = np.squeeze(lossy_image.numpy())
|
58 |
+
return numpy_lossy_image
|
59 |
+
|
60 |
+
def mostrar_resultados_prediccion(crop_image):
|
61 |
+
resultado_alexnet = modelo_alexnet.predecir(crop_image)
|
62 |
+
resultado_resnet50 = modelo_resnet50.predecir(crop_image)
|
63 |
+
return resultado_alexnet, resultado_resnet50
|
64 |
+
|
65 |
+
def obtener_valor_tag(image_byte, tag: int) -> str:
|
66 |
+
raw_tag_value = tfio.image.decode_dicom_data(image_byte, tag).numpy()
|
67 |
+
return raw_tag_value.decode('utf-8')
|
68 |
+
|
69 |
+
def obtener_informacion_archivo_dicom(image_bytes, tipo):
|
70 |
+
if tipo != 'storage':
|
71 |
+
image_bytes_values = image_bytes.getvalue()
|
72 |
+
else:
|
73 |
+
image_bytes_values = image_bytes#.getvalue()
|
74 |
+
data = {
|
75 |
+
"Nombre Paciente": obtener_valor_tag(image_bytes_values, tfio.image.dicom_tags.PatientsName),
|
76 |
+
"ID Paciente": obtener_valor_tag(image_bytes_values, tfio.image.dicom_tags.PatientID),
|
77 |
+
}
|
78 |
+
return data
|
79 |
+
|
80 |
+
def guardar_correccion():
|
81 |
+
df_resultados = dict()
|
82 |
+
|
83 |
+
df_resultados['resultado_alexnet_benigno'] = resultado_alexnet[0]
|
84 |
+
df_resultados['resultado_alexnet_maligno'] = resultado_alexnet[1]
|
85 |
+
df_resultados['resultado_alexnet_normal'] = resultado_alexnet[2]
|
86 |
+
df_resultados['resultado_resnet50_benigno'] = resultado_resnet50[0]
|
87 |
+
df_resultados['resultado_resnet50_maligno'] = resultado_resnet50[1]
|
88 |
+
df_resultados['resultado_resnet50_normal'] = resultado_resnet50[2]
|
89 |
+
df_resultados['correccion_benigno'] = st.session_state['correcion_benigno']
|
90 |
+
df_resultados['correccion_maligno'] = st.session_state['correcion_maligno']
|
91 |
+
df_resultados['correccion_normal'] = st.session_state['correcion_normal']
|
92 |
+
#df = pd.read_csv('./resultados_pruebas.csv')
|
93 |
+
df_resultados = pd.DataFrame(df_resultados, index=[0])
|
94 |
+
#df_completo = pd.concat([df, df_resultados], axis=0)
|
95 |
+
print(df_resultados)
|
96 |
+
df_resultados.to_csv('./resultados_pruebas.csv')
|
97 |
+
|
98 |
|
99 |
+
st.write("# Modelo de Machine Learning para el diagnostico del cancer de mama")
|
100 |
+
uploaded_file = st.file_uploader("Subir archivo DICOM", type=[".dcm"])
|
101 |
+
if uploaded_file:
|
102 |
+
dicom_file = cargar_dicom_file(uploaded_file, tipo='')
|
103 |
+
img = Image.fromarray(dicom_file)
|
104 |
+
rect = st_cropper(img,realtime_update=realtime_update, box_color=box_color,
|
105 |
+
aspect_ratio=aspect_ratio, return_type='box')
|
106 |
+
realizar_prediccion = st.button("Realizar predicción")
|
107 |
+
st.session_state['uploaded_file'] = uploaded_file.getvalue()
|
108 |
+
if realizar_prediccion:
|
109 |
+
st.empty()
|
110 |
+
crop = dicom_file[
|
111 |
+
rect['top']:rect['height'] + rect['top'],
|
112 |
+
rect['left']:rect['width'] + rect['left']]
|
113 |
+
resultado_alexnet, resultado_restnet50 = mostrar_resultados_prediccion( crop)
|
114 |
+
resultado_alexnet = np.squeeze(resultado_alexnet) * 100
|
115 |
+
resultado_resnet50 = np.squeeze(resultado_restnet50) * 100
|
116 |
+
datos_alexnet = {
|
117 |
+
"Probabilidad": resultado_alexnet,
|
118 |
+
"Clase": class_names
|
119 |
+
}
|
120 |
+
df_alexnet = pd.DataFrame(data=datos_alexnet).set_index('Clase')
|
121 |
+
datos_resnet50 = {
|
122 |
+
"Probabilidad": resultado_resnet50,
|
123 |
+
"Clase": class_names
|
124 |
+
}
|
125 |
+
df_resnet50 = pd.DataFrame(data=datos_resnet50).set_index('Clase')
|
126 |
+
st.write("### Probabilidades según tipo de tumor - AlexNet")
|
127 |
+
st.bar_chart(df_alexnet)
|
128 |
+
st.write("### Probabilidades según tipo de tumor - ResNet50")
|
129 |
+
st.bar_chart(df_resnet50)
|
130 |
+
df_form = obtener_informacion_archivo_dicom(uploaded_file, tipo='')
|
131 |
+
with st.form("Correcion") as form:
|
132 |
+
st.write("#### Tipo de tumorx")
|
133 |
+
st.slider("Benigno", 0, 100, 0, key='correcion_benigno')
|
134 |
+
st.slider("Maligno", 0, 100, 0, key='correcion_maligno')
|
135 |
+
st.slider("Normal", 0, 100, 0, key='correcion_normal')
|
136 |
+
submitted = st.form_submit_button("Realizar correccion", on_click=guardar_correccion)
|
clasificacion.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:959376a202beba507838e4fa0f1a48c845be0d7aca5eec9d5045b0505ff7f16b
|
3 |
+
size 11070475
|
clasificacion_alexnet.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1a7813fa953428ac413285f516f49475209f49e96fda27283c4d56cdc2a5e0fe
|
3 |
+
size 102959779
|