• Non ci sono risultati.

Il Software 3D-VIPE

5.3 Fase di acquisizione e decodifica dei DICOM

Se non ci sono errori nella fase di inizializzazione, l’indicatore DATA CAP- TURE inizia a lampeggiare a conferma del fatto che il sistema entra nella fase di acquisizione. 3D-VIPE prosegue la sua esecuzione decodificando uno per volta i singoli file della cartella selezionata, escludendo di fatto quelli della cartella “ct” (si ricorda questi file saranno gestiti in maniera differente).

Un file Dicom è codificato in binario [fig. 53], per permettere una maggiore versatilità nel trasferimento, come si è visto nel capitolo 4. La decodifica è ne- cessaria per rendere più facilmente leggibili e interpretabili le informazioni che contiene.

Un’estensione di LabVIEW utilizzata per lo sviluppo di questo software è il Biomedical Toolkit, che mette a disposizione particolari funzioni (tipicamente dei subVI) per lo sviluppo di programmi o applicazioni in ambito biomedico. Tra le varie funzioni, ce ne sono alcune appartenenti alla classe dell’imaging medico, che danno la possibilità elaborare le immagini secondo algoritmi già implemen-

tati e di gestire vari formati di immagini tra cui proprio i Dicom. Questa pecu- liarità è dovuta alla presenza di librerie che contengono funzioni in grado di leggere anche i parametri delle immagini, e quindi i metadati contenuti in un file Dicom.

Per velocizzare lo sviluppo del software, inizialmente sono state utilizzate queste librerie in maniera integrale o modificandole opportunamente, con lo scopo di decodificare gli attributi di un generico Dicom. Tuttavia questo approc- cio è risultato inadatto dal momento che queste librerie sono concepite per leg- gere attributi di dataset non annidati in sequenze, tipiche di IOD che presentano informazioni di tipo grafiche, con l’attributo Pixel Data. Gli elementi di un ge- nerico RT Plan IOD o in maniera più evidente quelli di uno RT Structure Set IOD, presentano d’altro canto una molteplicità di sequenze con elevato livello di annidamento.

Figura 53. Modalità di lettura di un file Dicom mediante visualizzatore di file binari. Nella colonna a destra si nota la decodifica in esadecimale

Per questi motivi si è reso necessario sviluppare un subVI ad hoc per leggere in maniera sequenziale tutti i singoli bit di un file Dicom, e ricostruire la strut- tura gerarchica che lo caratterizza. Questo è reso possibile grazie al subVI Read Single File.vi.

Il subVI acquisisce in ingresso il percorso sul disco del singolo file Dicom, lo apre e inizia a leggerlo grazie a particolari funzioni, in base alle regole stabilite all’interno del documento PS3.5 Data Value and Encoding. Esso è in grado di riconoscere l’inizio di un singolo Data Element in base all’informazione che porta il campo Tag; in seguito andando a decodificare le informazioni sul tipo di dato (che può essere unsigned byte, word, unsigned word, long, unsigned long, unsigned quad, single/double precision) e sulla lunghezza del campo Value Field, contenute rispettivamente in VR e VL, è in grado di stabilire quando termina lo stesso Data Element. Così è pronto a leggere un nuovo Data Element corrispon- dente ad un attributo univocamente determinato dal Tag.

Un Tag importante presente in tutti i Dataset di qualsiasi file Dicom, è il Transfer Syntax UID (0002,0100), che definisce il modo in cui i bit devono essere letti (little endian o big endian), e soprattutto se la codifica è di tipo Implicita o Esplicita.

Nel primo caso il dataset contiene solo 3 campi, poiché viene omesso quello relativo al VR; il software dopo aver riconosciuto questo Tag deve effettuare la decodifica di conseguenza, avendo cura di associare un dizionario che contenga le informazioni relative al VR per ogni singolo attributo dal Tag specifico. In questo modo sa come interpretare i bit contenuti nel campo Value Field, pur non avendo a disposizione in maniera esplicita l’informazione data da VR.

Nel secondo caso la decodifica è più semplice, dal momento che il programma ha a disposizione tutte le informazioni, relative al tipo di dato e alla sua lun- ghezza, date in maniere esplicita da VR.

Va detto che l’attributo Transfer Syntax rende noto anche il modo in cui vengono compresse le informazioni relative alle immagini, nell’elemento Pixel Data. In questo caso, questo tipo di informazione non è determinante per gli

obiettivi a cui è finalizzato lo sviluppo del software, dal momento che le imma- gini verranno lette con una funzione già implementata nel Biomedical Toolkit di LabVIEW (vedi par. 5.5.3).

Un'altra criticità emersa in fase di realizzazione di Read Single File.vi, era legata alla gestione dei Data Set annidati in sequenze. Il VR defi- nito con “SQ”, viene usato per definire Data Elements con campo Value Field che consiste in sequenze di zero o più Item (letteralmente, “oggetti”). SQ implica uno schema di codifica flessibile che può essere utilizzato per semplici strutture di Data Elements che si ripetono o per IOD complessi organizzati in una tipica strutture a cartelle. I Data Elements di tipo SQ possono anche essere utilizzati in maniera ricorsiva per contenere strutture annidate su più livelli.

Gli Items presenti all’interno di un Data Element SQ sono ordinati in ma- niera sequenziale. A ciascuno di essi è associato un numero cardinale che inizia da 1 e termina con quello degli Item totali della sequenza, associato all’ultimo Item presente in essa.

Il programma è in grado di riconoscere l’inizio e la fine degli Item o delle sequenze mediante tre specifici Tag che identificano gli elementi Item e non sono regolati secondo la convenzione del VR valida per tutti gli altri Elements; questi Tag sono:

- Item (FFFE,E000), Tag di apertura di un Item;

- Item Delimitation Item (FFFE,E00D), Tag di chiusura di una struttura Item;

- Sequence Delimitation Item (FFFE,E0DD), Tag di chiusura si una se- quenza di Item;

gli ultimi due Tags si utilizzano solamente nel caso di Item o sequenze con lunghezza indefinita (con il campo Value length =FFFFFFFF). Il programma è infatti in grado di stabilire per ogni data elements il suo livello di annidamento, per capire se fa parte o meno di una sequenza a prescindere dal fatto che la co- difica espressa con una sintassi implicita o esplicita o se gli elementi hanno VL

Questa parte di identificazione del livello di annidamento è gestita da una logica che utilizza contatori, booleani e strutture di tipo case, creati ad hoc per gestire tutti i possibili casi sopra citati.

In sintesi il sistema finora descritto viene implementato mediante un ciclo while contenente il codice per decodificare l’informazione binaria di un singolo Data Element secondo regole ben precise, andando ad identificare tutti i suoi campi, e associando ad esso un livello di annidamento. Il file viene analizzato in maniera sequenziale, byte dopo byte fino ad arrivare alla fine; in questo caso o in caso di insorgenza di errori il ciclo while si arresta e i dati vengono portati fuori e passati ai blocchi di elaborazione successivi.

Quello che avviene in seguito è la riorganizzazione dei vari data Element in 2 tipi di strutture, che sono le uscite del subVI Read Single File.vi:

- DICOM Attributes. Questo indicatore è un array in cui ogni Data Ele- ment è organizzato in cluster. Gli elementi del cluster sono quelli classici dei campi definiti in PS3.5, più il nome unico identificativo associato al Tag e il livello di annidamento (Nesting) calcolato al blocco precedente, come mostrato in figura 54.

- Tree. Il controllo di tipo tree fornisce all’utente una lista gerarchica di oggetti che possono essere selezionati singolarmente. È necessario convertire tutti i tipi di dato in stringhe di testo e accorpare i valori multipli dei Data element con VM maggiore di uno in un'unica stringa, separando gli elementi con una virgola. Ciascun oggetto viene messo in coda alla struttura in fase di costruzione, considerando il li- vello di annidamento a cui è associato [fig. 55].