Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoCorinna Mariani Modificato 5 anni fa
1
Ricerca di noduli polmonari in immagini di tomografia computerizzata (CT)
2
Com’è fatto un nodulo? Un nodulo polmonare è una formazione generalmente compatta, tendenzialmente sferica, di densità media (numero di Hounsfield) paragonabile a quella dell’acqua I noduli possono essere classificati in base alla loro posizione nel polmone, in n1, n2, n3 (ATTENZIONE! Classificazione NON standard!): n1: nodulo interno n2: nodulo cresciuto nelle vicinanze della pleura e ad essa connesso n3: nodulo originatosi nella pleura, alla quale è connesso in genere tramite un peduncolo
3
Tipologie di noduli polmonari
3
4
Esempio… Consideriamo una CT: cdPi152_S3
Il radiologo, operando tramite un software dotato di interfaccia grafica per la visualizzazione delle fette e la refertazione, costruisce il seguente record di informazioni: 1,45,301,134,3.15,0,n1,NC,SD,PD,T1,ND,ND,504,RadGS, 2,291,382,228,2.52,0,n2,NC,SD,PD,T1,ND,ND,504,RadGS, 3,70,300,255,4.57,0,n2,NC,SD,PD,T1,ND,ND,504,RadGS, 4,102,300,232,5.39,0,n1,ND,ND,ND,ND,ND,ND,504,RadGS, n. progressivo TIPOLOGIA COORDINATE x, y, z del centro (z è la slice) “RAGGIO” DEL NODULO (mm)
5
Immagini 2D dei noduli 1 2 3 4
6
Proviamo a visualizzare i noduli!
Abbiamo bisogno del file contenente il volume della CT (in formato analyze, di cui sfrutteremo i dati raw): cdPi152_S3_D0.hdr e cdPi152_S3_D0.img (hdr: header; img: voxel, dimensione file = w x h x d) Un file analyze può essere aperto da software free e.g. MRIcro Le coordinate indicate in MRIcro (in basso a sx) sono in mm; per ottenerle, moltiplicare le coordinate qui riportate per il voxel size (mm): [ ] .* [ ] = [ ]; La CT cdPi152_S3_D0 ha dimensioni x512x334 Carichiamo il file nel workspace di MATLAB
7
Codice MATLAB per caricare l’immagine e mostrare il nodulo in sezione
% apriamo e leggiamo il file contenente i dati dei voxel, 2 byte/voxel, int16 fid = fopen('cdPi152_S3_D0.img', 'r'); D = fread(fid, 'int16=>int16'); % senza spazi nella stringa! fclose(fid); nslices = size(D,1) / (512*512); % il file e’ una collezione lineare di int16, senza struttura di matrice 3D: % per ridare la struttura originale, usiamo % l’istruzione reshape (controllare % il workspace prima e dopo l’istruzione) D = reshape(D, [512, 512, nslices]); % visualizziamo una fetta in cui compaia il nodulo imshow(D(:, :, 134)', []) mostra_nodulo.m
8
Visualizzazione del nodulo in 3D (1)
Esistono diverse modalità di rappresentazione tridimensionale; la più semplice è la visualizzazione prospettica di una isosuperficie opportuna della densità (valore di grigio) [il nodulo non è un oggetto immerso nel vuoto!] Siccome un nodulo è un oggetto compatto e denso rispetto all’ambiente in cui si sviluppa (il parenchima polmonare), per visualizzare il nodulo in 3D occorre applicare all’immagine cdPi152_S3_D0 un’operazione di sogliatura (con valore di soglia deciso usando per esempio lo strumento impixelinfo), ottenendo cdPi152_S3_TH; Si evidenziano così nella CT gli oggetti costituiti da voxel densi; la frontiera degli oggetti così definiti (isosuperficie) sarà rappresentata in prospettiva
9
Ricerca dei candidati noduli in una CT (0)
La ricerca dei candidati noduli nella CT si effettua tramite l’operazione bwlabel applicata all’immagine dopo sogliatura cdPi152_S3_TH Per limitare il numero di falsi positivi, è opportuno preliminarmente segmentare la CT, ossia limitare al solo parenchima polmonare il volume in cui effettuare la ricerca L’operazione di segmentazione (che non sarà qui dettagliata) fornisce in output una maschera (cdPi152_S3_M4) che delimita il volume polmonare Combinando M4 con la CT originale sogliata, per ottenere il solo tessuto polmonare (cdPi152_S3_D2)
10
Maschera di segmentazione
11
Ricerca dei candidati noduli in una CT (1)
cerca_VOIs.m close all, clear % apriamo e leggiamo il file contenente i dati dei voxel, 2 byte/voxel, int16 fid = fopen('cdPi152_S3_D0.img', 'r'); D = fread(fid, 'int16=>int16'); fclose(fid); nslices = size(D, 1) / (512*512); % il file e’ una collezione lineare di int16, senza struttura di matrice 3D: % per ridare la struttura originale, usiamo l’istruzione reshape (controllare % il workspace prima e dopo l’istruzione) D = reshape(D, [512, 512, nslices]); % visualizziamo una fetta in cui compaia il nodulo figure imshow(D(:, :, 134)', []) … questa parte è identica a mostra_nodulo!
12
Ricerca dei candidati noduli in una CT (2)
% Ora applichiamo la soglia opportuna (grigio > -300) D = D > -300; figure imshow(int8(D(:, :, 134)'), []) % Prima di cercare gli oggetti connessi, usiamo la matrice % di segmentazione per limitare lo spazio di ricerca % (e quindi i falsi positivi e il tempo di calcolo) fid = fopen('cdPi152_S3_M4.img', 'r'); M = fread(fid, 'int8=>int8'); fclose(fid); M = logical(reshape(M, [512, 512, nslices])); imshow(M(:, :, 134)', []) % Operazione di masking (AND logico) D = D & M; imshow(D(:, :, 134)', []) … cerca_VOIs.m Soglia individuata tramite pixval; andrebbe trovato un valore buono per TUTTI i noduli, impresa difficile…
13
Ricerca dei candidati noduli in una CT (3)
% Cerchiamo oggetti connessi L = bwlabeln(D); % n dimensioni! figure imshow(L(:, :, 134)', []) stats = regionprops(L, 'Area', 'BoundingBox', 'Centroid', 'Image', 'PixelList'); % Filtro sul volume: consideriamo solo oggetti di dimensioni maggiori di 30 % pixel circa (cioe' noduli circa maggiori di 3x3x3 mm) Areas = [stats.Area]; ind = find(Areas > 30); stats = stats(ind); % l’oggetto di statistiche stats(1) ha etichetta ind(1) in L % ordiniamo per volume decrescente Areas = [stats.Area]; % lo rifaccio perche’ stats e’ cambiato [newAreas, s] = sort(Areas, 'descend'); stats = stats(s); ind = ind(s); … cerca_VOIs.m
14
Come usare il vettore di statistiche
>> stats stats = 219x1 struct array with fields: Area Centroid BoundingBox Image PixelList >> stats(1) ans = Area: Centroid: [ ] BoundingBox: [ ] Image: [454x317x291 logical] PixelList: [607327x3 double] >> stats(130).PixelList ans = ... mostra3D(stats(30).Image) per il codice di mostra3D, vedere le prox slide!
15
Quali features scegliere?
volume = numero di voxel accesi nella roi raggio = raggio della sfera più piccola contenente la ROI (sfera circoscritta) sfericità = rapporto tra l’area della superficie di una sfera avente volume pari a quello della ROI e l’area della superficie della ROI DA CALCOLARE DA CALCOLARE
16
Sfericità Wikipedia (http://en.wikipedia.org/wiki/Sphericity)
Sphericity is a measure of how spherical (round) an object is. As such, it is a specific example of a compactness measure of a shape. Defined by Wadell in 1935, the sphericity, Ψ, of a particle is the ratio of the surface area of a sphere (with the same volume as the given particle) to the surface area of the particle: where Vp is volume of the particle and Ap is the surface area of the particle
17
Ricerca dei candidati noduli in una CT (4)
cerca_VOIs.m for n = 1:length(stats) stats(n).RadiusC = 0.5 * sqrt(stats(n).BoundingBox(4) ^ 2 + \ stats(n).BoundingBox(5) ^ 2 + \ stats(n).BoundingBox(6) ^ 2); stats(n).Sphericity = stats(n).Area / (4.0/3 * pi * stats(n).RadiusC ^ 3); end >> stats stats = 219x1 struct array with fields: Area Centroid BoundingBox Image PixelList Frontier Surfarea RadiusC Sphericity
18
Visualizzazione noduli n1
cerca_VOIs.m % individuiamo un nodulo % sappiamo che il nodulo (1) si trova a 45,301,134, % ma dobbiamo INVERTIRE x con y!!! nn = []; for n = 1:length(stats) c = stats(n).Centroid; if pdist([301, 45, 134 ; c]) < 10 disp ('Trovato!') disp (n) nn = [nn, n]; end nn = nn(1); figure, mostra3D(stats(nn).Image) N = 95 102, 300, 232 N = 41
19
Visualizzazione noduli n2
cerca_VOIs.m N = 158 291,382,228 nodulo 2 (tipo n2) Il nodulo 3 (tipo n2) non si distingue 70,300,255 102, 300, 232
20
mostra3D function mostra3D(D) % %%% 3D % % figure;
% Inseriamo l'oggetto in una matrice un po' piu' grande: ho verificato che % se non lo si fa, compaiono dei buchi nella isosuperficie laddove essa % incontra la box s = size(D); D1 = zeros(s(1) + 4, s(2) + 4, s(3) + 4); D1(3:3+s(1)-1, 3:3+s(2)-1, 3:3+s(3)-1) = D; D = D1; clear D1 D = smooth3(double(D)); hiso = patch(isosurface(D),... 'FaceColor',[1,.75,.65],... 'EdgeColor','none'); view(45,30) axis tight daspect([1,1,.67]) % il .67 viene da 1/1.5 lightangle(45,30); set(gcf,'Renderer','zbuffer'); lighting phong isonormals(D,hiso) %set(hcap,'AmbientStrength',.6) set(hiso,'SpecularColorReflectance',0,'SpecularExponent',50) box
21
VOIs save stats stats clear load stats mostra3D(stats(2).Image)
22
Statistiche sui noduli
Nodulo 1 (indice 95) >> stats(95) ans = Area: 80 Centroid: [ ] BoundingBox: [ ] Image: [6x7x4 logical] PixelList: [80x3 double] RadiusC: Sphericity: Nodulo 4 (indice 41) >> stats(41) Area: 222 Centroid: [ ] BoundingBox: [ ] Image: [12x12x8 logical] PixelList: [222x3 double] RadiusC: Sphericity: Nodulo 2 (indice 158) >> stats(158) Area: 43 Centroid: [ ] BoundingBox: [ ] Image: [8x7x3 logical] PixelList: [43x3 double] RadiusC: Sphericity:
23
noduli.m noduli.m: carica “noduli_per_master.mat” e calcola delle statistiche sui dati, allenando poi un classificatore lineare o una rete neurale artificiale >> noduli >> confronto = [labtest y] confronto = <omissis> TP = 12 FN = 2 FP = 31 TN = 1087 sensitivity = specificity = Il file di dati contiene le feature calcolate su un gran numero di noduli e non-noduli (rispettivamente 27 e 2236) provenienti da alcune TC polmonari. Le feature sono: volume - raggio mm - sfericita' e intensita' media (colonne da 1 a 4)
24
Distribuzioni e scatter-plot delle features
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.