dmolino commited on
Commit
822dcdc
·
verified ·
1 Parent(s): d61e08d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +463 -11
app.py CHANGED
@@ -1,20 +1,472 @@
1
  import streamlit as st
2
- from transformers import pipeline
 
 
 
 
 
3
  from PIL import Image
 
 
4
 
5
- pipeline = pipeline(task="image-classification", model="julien-c/hotdog-not-hotdog")
6
 
7
- st.title("Hot Dog? Or Not?")
 
 
 
8
 
9
- file_name = st.file_uploader("Upload a hot dog candidate image")
10
 
11
- if file_name is not None:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  col1, col2 = st.columns(2)
13
 
14
- image = Image.open(file_name)
15
- col1.image(image, use_column_width=True)
16
- predictions = pipeline(image)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
- col2.header("Probabilities")
19
- for p in predictions:
20
- col2.subheader(f"{ p['label'] }: { round(p['score'] * 100, 1)}%")
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import tifffile
3
+ import pydicom
4
+ from scipy.ndimage import zoom
5
+ import torch
6
+ #from core.models.dani_model import dani_model
7
+ import numpy as np
8
  from PIL import Image
9
+ import base64
10
+ import time
11
 
 
12
 
13
+ # Funzione per convertire un'immagine in base64
14
+ def image_to_base64(image_path):
15
+ with open(image_path, "rb") as img_file:
16
+ return base64.b64encode(img_file.read()).decode()
17
 
 
18
 
19
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
20
+
21
+ # Dati di esempio predefiniti
22
+ esempi = {
23
+ "FRO -> LAT": {'FRO': 'FtoL.png', 'LAT': 'LfromF.png'},
24
+ "FRO -> REP": {'FRO': '31d9847f-987fcf63-704f7496-d2b21eb8-63cd973e.tiff', 'REP': 'Small bilateral pleural effusions, left greater than right.'},
25
+ "FRO -> LAT + REP": {'FRO': '81bca127-0c416084-67f8033c-ecb26476-6d1ecf60.tiff', 'LAT': 'd52a0c5c-bb7104b0-b1d821a5-959984c3-33c04ccb.tiff', 'REP': 'No acute intrathoracic process. Heart Size is normal. Lungs are clear. No pneumothorax'},
26
+ "LAT -> FRO": {'LAT': 'LtoF.png', 'FRO': 'FfromL.png'},
27
+ "LAT -> REP": {'LAT': 'd52a0c5c-bb7104b0-b1d821a5-959984c3-33c04ccb.tiff', 'REP': 'no acute cardiopulmonary process. if concern for injury persists, a dedicated rib series with markers would be necessary to ensure no rib fractures.'},
28
+ "LAT -> FRO + REP": {'LAT': 'reald52a0c5c-bb7104b0-b1d821a5-959984c3-33c04ccb.tiff', 'FRO': 'ab37274f-b4c1fc04-e2ff24b4-4a130ba3-cd167968.tiff', 'REP': 'No acute intrathoracic process. If there is strong concern for rib fracture, a dedicated rib series may be performed.'},
29
+ "REP -> FRO": {'REP': 'Left lung opacification which may reflect pneumonia superimposed on metastatic disease.', 'FRO': '02aa804e-bde0afdd-112c0b34-7bc16630-4e384014.tiff'},
30
+ "REP -> LAT": {'REP': 'Bilateral pleural effusions, cardiomegaly and mild edema suggest fluid overload.', 'LAT': '489faba7-a9dc5f1d-fd7241d6-9638d855-eaa952b1.tiff'},
31
+ "REP -> FRO + LAT": {'REP': 'No acute intrathoracic process. The lungs are clean and heart is normal size.', 'FRO': 'f27ba7cd-44486c2e-29f3e890-f2b9f94e-84110448.tiff', 'LAT': 'b20c9570-de77944a-b8604ba0-73305a7b-d608a72b.tiff'},
32
+ "FRO + LAT -> REP": {'FRO': '95856dd1-5878b5b1-9c104817-760c0122-6187946f.tiff', 'LAT': '3723d912-71940d69-4fef2dd2-27af5a7b-127ba20c.tiff', 'REP': 'Opacities in the right upper or middle lobe, maybe early pneumonia.'},
33
+ "FRO + REP -> LAT": {'FRO': 'e7f21453-7956d79a-44e44614-fae8ff16-d174d1a0.tiff', 'REP': 'No focal consolidation.', 'LAT': '8037e6b9-06367464-a4ccd63a-5c5c5a81-ce3e7ffc.tiff'},
34
+ "LAT + REP -> FRO": {'LAT': '02c66644-b1883a91-54aed0e7-62d25460-398f9865.tiff', 'REP': 'No evidence of acute cardiopulmonary process.', 'FRO': 'b1f169f1-12177dd5-2fa1c4b1-7b816311-85d769e9.tiff'}
35
+ }
36
+
37
+
38
+ # CSS per personalizzare il tema
39
+ st.markdown("""
40
+ <style>
41
+ /* Sfondo scuro */
42
+ body {
43
+ background-color: #121212;
44
+ color: white;
45
+ }
46
+ /* Personalizzazione del titolo */
47
+ .title {
48
+ font-size: 35px !important;
49
+ font-weight: bold;
50
+ color: #f63366;
51
+ }
52
+ /* Personalizzazione dei sottotitoli e testi principali */
53
+ .stText, .stButton, .stMarkdown {
54
+ font-size: 18px !important;
55
+ }
56
+ </style>
57
+ """, unsafe_allow_html=True)
58
+
59
+
60
+ # Sostituisci questo con il link dell'immagine online
61
+ logo_1_path = "./DEMO/Loghi/Logo_UCBM.png" # Sostituisci con il percorso del primo logo
62
+ logo_2_path = "./DEMO/Loghi/Logo UmU.png" # Sostituisci con il percorso del secondo logo
63
+ logo_3_path = "./DEMO/Loghi/Logo COSBI.png" # Sostituisci con il percorso del terzo logo
64
+ logo_4_path = "./DEMO/Loghi/logo trasparent.png" # Sostituisci con il percorso del quarto logo
65
+ # Converti le immagini in base64
66
+ logo_1_base64 = image_to_base64(logo_1_path)
67
+ logo_2_base64 = image_to_base64(logo_2_path)
68
+ logo_3_base64 = image_to_base64(logo_3_path)
69
+ logo_4_base64 = image_to_base64(logo_4_path)
70
+
71
+ # CSS per posizionare i loghi in basso a destra e renderli piccoli
72
+ st.markdown(f"""
73
+ <style>
74
+ .footer {{
75
+ position: fixed;
76
+ bottom: 20px;
77
+ right: 20px;
78
+ z-index: 100;
79
+ display: flex;
80
+ gap: 10px; /* Spazio tra i loghi */
81
+ }}
82
+ .footer img {{
83
+ height: 60px; /* Altezza dei loghi */
84
+ width: auto; /* Mantiene il rapporto di aspetto originale */
85
+ }}
86
+ </style>
87
+ <div class="footer">
88
+ <img src="data:image/png;base64,{logo_1_base64}" alt="Logo 1">
89
+ <img src="data:image/png;base64,{logo_2_base64}" alt="Logo 2">
90
+ <img src="data:image/png;base64,{logo_3_base64}" alt="Logo 3">
91
+ <img src="data:image/png;base64,{logo_4_base64}" alt="Logo 4">
92
+ </div>
93
+ """, unsafe_allow_html=True)
94
+
95
+ # Inizializzazione dello stato della sessione
96
+ if 'step' not in st.session_state:
97
+ st.session_state['step'] = 1
98
+ if 'selected_option' not in st.session_state:
99
+ st.session_state['selected_option'] = None
100
+ if 'frontal_file' not in st.session_state:
101
+ st.session_state['frontal_file'] = None
102
+ if 'lateral_file' not in st.session_state:
103
+ st.session_state['lateral_file'] = None
104
+ if 'report' not in st.session_state:
105
+ st.session_state['report'] = ""
106
+ if 'inputs' not in st.session_state:
107
+ st.session_state['inputs'] = None
108
+ if 'outputs' not in st.session_state:
109
+ st.session_state['outputs'] = None
110
+ if 'frontal' not in st.session_state:
111
+ st.session_state['frontal'] = None
112
+ if 'lateral' not in st.session_state:
113
+ st.session_state['lateral'] = None
114
+ if 'report' not in st.session_state:
115
+ st.session_state['report'] = ""
116
+ if 'generate' not in st.session_state:
117
+ st.session_state['generate'] = False
118
+
119
+ # Inizializza inference_tester solo una volta
120
+ if 'inference_tester' not in st.session_state:
121
+ st.session_state['inference_tester'] = 1
122
+
123
+ # Usa inference_tester dalla sessione
124
+ inference_tester = st.session_state['inference_tester']
125
+
126
+
127
+ st.markdown('<h1 style="text-align: center" class="title">MedCoDi-M</h1>', unsafe_allow_html=True)
128
+
129
+ if st.session_state['step'] == 1:
130
+ # Breve descrizione del lavoro
131
+ st.markdown("""
132
+ <div style='text-align: justify; font-size: 18px; line-height: 1.6;'>
133
+ This work introduces MedCoDi-M, a novel multi-prompt vision-language model for multi-modal medical data generation.
134
+ In this demo, you will be able to perform various generation tasks including frontal and lateral chest X-rays and clinical report generation.
135
+ MedCoDi-M enables flexible, any-to-any generation across different medical data modalities, utilizing contrastive learning and a modular approach for enhanced performance.
136
+ </div>
137
+ """, unsafe_allow_html=True)
138
+
139
+ # lasciamo un po' di spazio
140
+ st.markdown('<br>', unsafe_allow_html=True)
141
+
142
+ # Immagine con didascalia migliorata e con dimensione della caption aumentata
143
+ image_path = "./DEMO/Loghi/model_final.png" # Sostituisci con il percorso della tua immagine
144
+ st.image(image_path, caption='', use_column_width=True)
145
+
146
+ # Caption con dimensione del testo migliorata
147
+ st.markdown("""
148
+ <div style='text-align: center; font-size: 16px; font-style: italic; margin-top: 10px;'>
149
+ Framework of MedCoDi-M: This demo allows you to generate frontal and lateral chest X-rays, as well as medical reports, through the MedCoDi-M model.
150
+ </div>
151
+ """, unsafe_allow_html=True)
152
+
153
+ # lasciamo un po' di spazio
154
+ st.markdown('<br>', unsafe_allow_html=True)
155
+
156
+ # Bottone con testo "Try it out"
157
+ if st.button("Try it out!"):
158
+ st.session_state['step'] = 2
159
+ st.rerun()
160
+
161
+
162
+ # Fase 1: Selezione dell'opzione
163
+ if st.session_state['step'] == 2:
164
+ # Opzioni disponibili
165
+ options = [
166
+ "FRO -> LAT", "FRO -> REP", "FRO -> LAT + REP",
167
+ "LAT -> FRO", "LAT -> REP", "LAT -> FRO + REP",
168
+ "REP -> FRO", "REP -> LAT", "REP -> FRO + LAT",
169
+ "FRO + LAT -> REP", "FRO + REP -> LAT", "LAT + REP -> FRO"
170
+ ]
171
+
172
+ # Messaggio di selezione con dimensione aumentata
173
+ st.markdown(
174
+ "<h4 style='text-align: justify'><strong>Select the type of generation you want to perform: (FRO = Frontal, LAT = Lateral, REP = Report)</strong></h4>",
175
+ unsafe_allow_html=True)
176
+
177
+ # Aumentare la dimensione di "Please select an option:"
178
+ st.markdown(
179
+ "<h4 style='text-align: justify'><strong>Please select an option:</strong></h4>",
180
+ unsafe_allow_html=True)
181
+
182
+ # Reset esplicito del valore di `selectbox` in caso di reset
183
+ st.session_state['selected_option'] = st.selectbox(
184
+ "", options, key='selectbox_option', index=0) # Rimuoviamo il testo dal selectbox
185
+
186
+ st.markdown('<br>', unsafe_allow_html=True)
187
+
188
+ # Creiamo colonne per i pulsanti
189
+ col1, col2, col3 = st.columns(3)
190
+
191
+ # Pulsante per procedere con l'inferenza
192
+ with col1:
193
+ if st.button("Inference"):
194
+ st.session_state['step'] = 3 # Passa al passo 3
195
+ st.rerun()
196
+
197
+ # Pulsante per provare un esempio
198
+ with col2:
199
+ if st.button("Try an example"):
200
+ st.session_state['step'] = 5 # Passa al passo 5
201
+ st.rerun()
202
+
203
+ # Pulsante per tornare all'inizio
204
+ with col3:
205
+ if st.button("Return to the beginning"):
206
+ # Ripristina lo stato della sessione
207
+ st.session_state['step'] = 1
208
+ st.session_state['selected_option'] = None
209
+ st.session_state['selected_option2'] = None
210
+ st.session_state['frontal_file'] = None
211
+ st.session_state['lateral_file'] = None
212
+ st.session_state['report'] = ""
213
+ st.rerun()
214
+
215
+
216
+ # Fase 2: Caricamento file
217
+ if st.session_state['step'] == 3:
218
+ st.markdown(
219
+ f"<h4 style='text-align: justify'><strong>You selected: {st.session_state['selected_option']}. Now, please upload the required files below:</strong></h4>",
220
+ unsafe_allow_html=True)
221
+
222
+ # Carica l'immagine frontale
223
+ if "FRO" in st.session_state['selected_option'].split(" ->")[0]:
224
+ st.markdown("<h5 style='font-size: 18px;'>Load the Frontal X-ray in DICOM format</h5>", unsafe_allow_html=True)
225
+ st.session_state['frontal_file'] = st.file_uploader("", type=["dcm"])
226
+
227
+ # Carica l'immagine laterale
228
+ if "LAT" in st.session_state['selected_option'].split(" ->")[0]:
229
+ st.markdown("<h5 style='font-size: 18px;'>Load the Lateral X-ray in DICOM format</h5>", unsafe_allow_html=True)
230
+ st.session_state['lateral_file'] = st.file_uploader("", type=["dcm"])
231
+
232
+ # Inserisci il report clinico
233
+ if "REP" in st.session_state['selected_option'].split(" ->")[0]:
234
+ st.markdown("<h5 style='font-size: 18px;'>Type the clinical report</h5>", unsafe_allow_html=True)
235
+ st.session_state['report'] = st.text_area("", value=st.session_state['report'])
236
+
237
+ # lasciamo un po' di spazio
238
+ st.markdown('<br>', unsafe_allow_html=True)
239
+
240
+ # Creare colonne per allineare i pulsanti in orizzontale
241
  col1, col2 = st.columns(2)
242
 
243
+ with col1:
244
+ if st.button("Start Generation"):
245
+ frontal = None
246
+ lateral = None
247
+ report = None
248
+ # Dato che questo step è velocissimo, prima di procedere mettiamo una finta barra di caricamento di 3 secondi
249
+ with st.spinner("Preprocessing the data..."):
250
+ time.sleep(3)
251
+ # Controllo che i file necessari siano stati caricati
252
+ if "FRO" in st.session_state['selected_option'].split(" ->")[0] and not st.session_state['frontal_file']:
253
+ st.error("Load the Frontal image.")
254
+ elif "LAT" in st.session_state['selected_option'].split(" ->")[0] and not st.session_state['lateral_file']:
255
+ st.error("Load the Lateral image.")
256
+ elif "REP" in st.session_state['selected_option'].split(" ->")[0] and not st.session_state['report']:
257
+ st.error("Type the clinical report.")
258
+ else:
259
+ st.write(f"Execution of: {st.session_state['selected_option']}")
260
+
261
+ # Carica l'immagine e avvia l'inferenza
262
+ if st.session_state['frontal_file']:
263
+ dicom = pydicom.dcmread(st.session_state['frontal_file'])
264
+ image = dicom.pixel_array
265
+ if dicom.PhotometricInterpretation == 'MONOCHROME1':
266
+ image = (2 ** dicom.BitsStored - 1) - image
267
+ if dicom.ImagerPixelSpacing != [0.139, 0.139]:
268
+ zoom_factor = [0.139 / dicom.ImagerPixelSpacing[0], 0.139 / dicom.ImagerPixelSpacing[1]]
269
+ image = zoom(image, zoom_factor)
270
+ image = image / (2 ** dicom.BitsStored - 1)
271
+ # Se l'immagine non è quadrata, facciamo padding
272
+ if image.shape[0] != image.shape[1]:
273
+ diff = abs(image.shape[0] - image.shape[1])
274
+ pad_size = diff // 2
275
+ if image.shape[0] > image.shape[1]:
276
+ padded_image = np.pad(image, ((0, 0), (pad_size, pad_size)))
277
+ else:
278
+ padded_image = np.pad(image, ((pad_size, pad_size), (0, 0)))
279
+ # Resizing a 256x256 e a 512x512
280
+ zoom_factor = [256 / padded_image.shape[0], 256 / padded_image.shape[1]]
281
+ image_256 = zoom(padded_image, zoom_factor)
282
+ frontal = image_256
283
+ if frontal.dtype != np.uint8:
284
+ frontal2 = (255 * (frontal - frontal.min()) / (frontal.max() - frontal.min())).astype(np.uint8)
285
+ frontal = torch.tensor(frontal, dtype=torch.float32).unsqueeze(0).unsqueeze(0)
286
+ frontal2 = Image.fromarray(frontal2)
287
+ st.write("Frontal Image loaded successfully!")
288
+ # Mostra l'immagine caricata
289
+ st.image(frontal2, caption="Frontal Image Loaded", use_column_width=True)
290
+ if st.session_state['lateral_file']:
291
+ dicom = pydicom.dcmread(st.session_state['lateral_file'])
292
+ image = dicom.pixel_array
293
+ if dicom.PhotometricInterpretation == 'MONOCHROME1':
294
+ image = (2 ** dicom.BitsStored - 1) - image
295
+ if dicom.ImagerPixelSpacing != [0.139, 0.139]:
296
+ zoom_factor = [0.139 / dicom.ImagerPixelSpacing[0], 0.139 / dicom.ImagerPixelSpacing[1]]
297
+ image = zoom(image, zoom_factor)
298
+ image = image / (2 ** dicom.BitsStored - 1)
299
+ # Se l'immagine non è quadrata, facciamo padding
300
+ if image.shape[0] != image.shape[1]:
301
+ diff = abs(image.shape[0] - image.shape[1])
302
+ pad_size = diff // 2
303
+ if image.shape[0] > image.shape[1]:
304
+ padded_image = np.pad(image, ((0, 0), (pad_size, pad_size)))
305
+ else:
306
+ padded_image = np.pad(image, ((pad_size, pad_size), (0, 0)))
307
+ # Resizing a 256x256 e a 512x512
308
+ zoom_factor = [256 / padded_image.shape[0], 256 / padded_image.shape[1]]
309
+ image_256 = zoom(padded_image, zoom_factor)
310
+ lateral = image_256
311
+ if lateral.dtype != np.uint8:
312
+ lateral2 = (255 * (lateral - lateral.min()) / (lateral.max() - lateral.min())).astype(np.uint8)
313
+ lateral = torch.tensor(lateral, dtype=torch.float32).unsqueeze(0).unsqueeze(0)
314
+ lateral2 = Image.fromarray(lateral2)
315
+ st.write("Lateral Image loaded successfully!")
316
+ st.image(lateral2, caption="Lateral Image Loaded", use_column_width=True)
317
+ if st.session_state['report']:
318
+ report = st.session_state['report']
319
+ st.write(f"Loaded Report: {report}")
320
+
321
+ inputs = []
322
+ if "FRO" in st.session_state['selected_option'].split(" ->")[0]:
323
+ inputs.append('frontal')
324
+ if "LAT" in st.session_state['selected_option'].split(" ->")[0]:
325
+ inputs.append('lateral')
326
+ if "REP" in st.session_state['selected_option'].split(" ->")[0]:
327
+ inputs.append('text')
328
+
329
+ # Ora vediamo cosa c'è dopo la freccia
330
+ outputs = []
331
+ if "FRO" in st.session_state['selected_option'].split(" ->")[1]:
332
+ outputs.append('frontal')
333
+ if "LAT" in st.session_state['selected_option'].split(" ->")[1]:
334
+ outputs.append('lateral')
335
+ if "REP" in st.session_state['selected_option'].split(" ->")[1]:
336
+ outputs.append('text')
337
+
338
+ # Ultima cosa che va fatta è passare allo step 4, prima di farlo però, tutte le variabili che ci servono
339
+ # devono essere salvate nello stato della sessione
340
+ st.session_state['inputs'] = inputs
341
+ st.session_state['outputs'] = outputs
342
+ st.session_state['frontal'] = frontal
343
+ st.session_state['lateral'] = lateral
344
+ st.session_state['report'] = report
345
+ st.session_state['generate'] = True
346
+
347
+ st.session_state['step'] = 4
348
+ st.rerun()
349
+
350
+ with col2:
351
+ if st.button("Return to the beginning"):
352
+ # Ripristina lo stato della sessione
353
+ st.session_state['step'] = 1
354
+ st.session_state['selected_option'] = None
355
+ st.session_state['selected_option2'] = None
356
+ st.session_state['frontal_file'] = None
357
+ st.session_state['lateral_file'] = None
358
+ st.session_state['report'] = ""
359
+ st.rerun()
360
+
361
+ if st.session_state['step'] == 4:
362
+ st.write("Generation completed successfully!")
363
+ st.session_state['generate'] = False
364
+
365
+ if st.button("Return to the beginning"):
366
+ # Ripristina lo stato della sessione
367
+ st.session_state['generate'] = False
368
+ st.session_state['step'] = 1
369
+ st.session_state['selected_option'] = None
370
+ st.session_state['frontal_file'] = None
371
+ st.session_state['lateral_file'] = None
372
+ st.session_state['report'] = ""
373
+ st.session_state['inputs'] = None
374
+ st.session_state['outputs'] = None
375
+ st.session_state['frontal'] = None
376
+ st.session_state['lateral'] = None
377
+ st.session_state['report'] = ""
378
+ st.rerun()
379
+
380
+ if st.session_state['step'] == 5:
381
+ st.markdown(
382
+ f"<h4 style='text-align: justify'><strong>You selected: {st.session_state['selected_option']}</strong></h4>",
383
+ unsafe_allow_html=True)
384
+
385
+ inputs = []
386
+ if "FRO" in st.session_state['selected_option'].split(" ->")[0]:
387
+ inputs.append('FRO')
388
+ if "LAT" in st.session_state['selected_option'].split(" ->")[0]:
389
+ inputs.append('LAT')
390
+ if "REP" in st.session_state['selected_option'].split(" ->")[0]:
391
+ inputs.append('REP')
392
+
393
+ outputs = []
394
+ if "FRO" in st.session_state['selected_option'].split(" ->")[1]:
395
+ outputs.append('FRO')
396
+ if "LAT" in st.session_state['selected_option'].split(" ->")[1]:
397
+ outputs.append('LAT')
398
+ if "REP" in st.session_state['selected_option'].split(" ->")[1]:
399
+ outputs.append('REP')
400
+
401
+ esempio = esempi[st.session_state['selected_option']]
402
+
403
+ # Mostra i file associati all'esempio
404
+ st.markdown(
405
+ "<h3 style='text-align: justify'><strong>INPUTS</strong></h3>",
406
+ unsafe_allow_html=True)
407
+
408
+ # Colonne per gli INPUTS
409
+ input_cols = st.columns(len(inputs))
410
+
411
+ for idx, inp in enumerate(inputs):
412
+ with input_cols[idx]:
413
+ if inp == 'FRO':
414
+ path = "./DEMO/ESEMPI/" + esempio['FRO']
415
+ print(path)
416
+ if path.endswith(".tiff"):
417
+ im = tifffile.imread(path)
418
+ im = np.clip(im, 0, 1)
419
+ elif path.endswith(".png"):
420
+ im = Image.open(path)
421
+ st.image(im, caption="Frontal Image")
422
+ elif inp == 'LAT':
423
+ path = "./DEMO/ESEMPI/" + esempio['LAT']
424
+ if path.endswith(".tiff"):
425
+ im = tifffile.imread(path)
426
+ im = np.clip(im, 0, 1)
427
+ elif path.endswith(".png"):
428
+ im = Image.open(path)
429
+ st.image(im, caption="Lateral Image")
430
+ elif inp == 'REP':
431
+ st.write(f"Report: {esempio['REP']}")
432
+
433
+ st.markdown(
434
+ "<h3 style='text-align: justify'><strong>OUTPUTS</strong></h3>",
435
+ unsafe_allow_html=True)
436
+
437
+ # Colonne per gli OUTPUTS
438
+ output_cols = st.columns(len(outputs))
439
+
440
+ for idx, out in enumerate(outputs):
441
+ with output_cols[idx]:
442
+ if out == 'FRO':
443
+ path = "./DEMO/ESEMPI/" + esempio['FRO']
444
+ if path.endswith(".tiff"):
445
+ im = tifffile.imread(path)
446
+ # facciamo clamp tra 0 e 1
447
+ im = np.clip(im, 0, 1)
448
+ elif path.endswith(".png"):
449
+ im = Image.open(path)
450
+ st.image(im, caption="Frontal Image")
451
+ elif out == 'LAT':
452
+ path = "./DEMO/ESEMPI/" + esempio['LAT']
453
+ if path.endswith(".tiff"):
454
+ im = tifffile.imread(path)
455
+ # facciamo clamp tra 0 e 1
456
+ im = np.clip(im, 0, 1)
457
+ elif path.endswith(".png"):
458
+ im = Image.open(path)
459
+ st.image(im, caption="Lateral Image")
460
+ elif out == 'REP':
461
+ st.write(f"Report: {esempio['REP']}")
462
 
463
+ # Pulsante per tornare all'inizio
464
+ if st.button("Return to the beginning"):
465
+ # Ripristina lo stato della sessione
466
+ st.session_state['step'] = 1
467
+ st.session_state['selected_option'] = None
468
+ st.session_state['selected_option2'] = None
469
+ st.session_state['frontal_file'] = None
470
+ st.session_state['lateral_file'] = None
471
+ st.session_state['report'] = ""
472
+ st.rerun()