Medicinska Bilder, TSBB3 Lab: Mätvärden på Medicinska Bilder Maria Magnusson, 22 Senaste updatering: september 25 Avdelningen för Datorseende, Institutionen för Systemteknik Linköpings Universitet Introduktion I denna laboration ska vi göra olika mätningar på bilder. Laborationen behövs som förkunskap till den senare laboration om SPECT. 2 Förberedelser inför laborationen Läs igenom hela laborationshandledningen noggrant. Valda delar av senaste föreläsningen ger den teori som behövs. Lös förberedelseuppgifterna i lab-handledningen innan laborationstillfället! De är markerade med en pekande hand. 3 Laborationen 3. Start Laborationen kommer att ske i MATLAB. Börja med att logga in och öppna ett terminal-fönster från bakgrunden. Ge därefter följande kommandon. % matlab > initcourse( TSBB3 ); Kommandot initcourse( TSBB3 ) sätter upp korrekta path :ar i MAT- LAB så att önskade filer hittas. De program som vi ska använda ligger på /site/edu/bb/medicinskabilder/noise.
Kopiera dessa filer till din hem-katalog och kör programmet NOISE.m. En fyrdelad test-bild med fyra områden med värdena, 7, 4 och visas till vänster, se Fig.. Matlab-koden för detta program är: % Image size 2 % ========== 3 N = 28; 4 5 % Compose test image 6 % ================== 7 im = zeros(n,n); 8 im(:n/2,:n/2) = ; 9 im(n/2+:n,:n/2) = 4; im(:n/2,n/2+:n) = 7; im(n/2+:n,n/2+:n) = ; 2 3 figure() 4 colormap(jet) 5 subplot(2,2,), imagesc(im, [ ]) 6 axis image, colorbar 7 title( a) original image ) a) original image 2 4 2 4 Figur : a) Testbild. 5 Öppna programmet NOISE.m i en editor och lägg nu till gaussiskt brus med medelvärde mean= och standardavvikelse std= : gnoiseim = im + * randn(n,n); Medelvärdet kan beräknas i en 5 5-omgivning runt varje pixel. Enklast gör man detta genom att falta original-bilden med ett 5 5-filter fyllt med ettor och dividera med antalet ettor: kernelsize = 5; kernel = ones(kernelsize,kernelsize)/(kernelsize^2); gaver = conv2(gnoiseim, kernel, same ); Lägg till också detta i koden och visa resultatet i en bild till höger. Det ska se ut som i Fig. 2. Lyckades ni? 2
a) original image b) local mean 2 4 2 4 5 2 4 2 4 5 Figur 2: a) Testbild med pålagt gaussiskt brus. b) Lokalt medelvärde. 3.2 Mätvärden på bild med gaussiskt brus Uppskatta (stickprovs-)standardavvikelsen av originalbilden och visa den under originalbilden. Använd lika stora omgivningar som för beräkning av medelvärden. Vilka kommandon ger du? Nedan finns en tabell med värden i originalbilden. Enligt Matlab-koden ovan är medelvärdena, 7, 4, i de fyra områdena och standardavvikelsen på det pålagda gaussiska bruset. Komplettera tabellen nedan ungefärligt genom att klicka i bilderna. Område övre vänster övre höger nedre vänster nedre höger värde 7 4 ett uppskattat medelvärde standardavvikelse en uppskattad standardavvikelse förväntat CV-värde ett uppskattat CV-värde Fyll i raden förväntat CV-värde i tabellen ovan. 3
Uppskatta CV-värdet av originalbilden och visa den snett under originalbilden. Använd lika stora omgivningar som för beräkning av medelvärden. Komplettera tabellen ovan genom att klicka i bilderna. Hur lika bör de uppskattade värdena i de två tabellerna ovan vara de korrekta värdena? Välj mellan "exakt lika, ungefär lika och behöver inte vara lika. 3.3 Mätvärden på bild med poissonbrus Poissonbrus är ju som bekant viktigt i medicinska sammanhang. Nu ska vi göra om mätningarna i avsnitt 3.2 på poissonbrus istället för gaussiskt brus. Vilka värden ska gälla för standardavvikelsen i de de fyra områdena med medelvärde, 7, 4,? Kopiera filen NOISE.m till NOISEpoisson.m. Ersätt det gaussiska bruset med poissonbrus i NOISEpoisson.m. Den approximativa metoden för att skapa poissonbrus beskrevs på föreläsningen: Skapa först approximativt poissonbrus med hjälp av gaussiskt brus. Lokalisera därefter pixlar med negativa värden. I dessa pixlar: kasta tärningen igen tills ett positivt värde erhålls. Kodskelett för Poissonbrus finns i filen Poisson.m som ser ut så här: % Add Poisson noise 2 % ================== 3 pnoiseim = im + XXX; % Add Poisson noise to the image. Replace XXX! 4 [y,x] = find(pnoiseim<); % Locate positions of negative values 5 for k = :size(y,) % Redo the calculation for these positions 6 posval = ; 7 while (posval==) % Compute ONE new noise value. 8 val = im(y(k),x(k)) + YYY; % Replace YYY! 9 if (val>) posval = ; end end pnoiseim(y(k),x(k)) = val; 2 end De två översta bilderna ska se ut som i Fig. 3. Vad ersätter ni XXX med och vad ersätter ni YYY med? Beräkna nu CV-värdena på samma sätt som i avsnitt 3.2 och fyll i tabellen nedan. 4
Område övre vänster övre höger nedre vänster nedre höger värde 7 4 standardavvikelse förväntat CV-värde ett uppskattat CV-värde a) original image b) local mean 2 4 2 4 5 2 4 2 4 5 Figur 3: a) Testbild med pålagt poissonbrus. b) Lokalt medelvärde. 3.4 Krympning och etikettering Matlab-koden för programmet CVL.m visas nedan. Då det exekveras visas en binär bild med bokstäverna CVL till vänster och till höger visas resultatet av krympning (erosion) av två lager pixlar, se Fig. 4. load CVLim 2 3 SE = [ ; 4 ; 5 ; 6 ; 7 ]; 8 9 CVLerode = imerode(cvlim, SE); figure(), colormap(gray) 2 subplot(2,2,), imagesc(cvlim, [ ]) 3 axis image, colorbar 4 title( original image ) 5 subplot(2,2,2), imagesc(cvlerode, [ ]) 6 axis image, colorbar 7 title( eroded image ) I en senare lab om SPECT ska vi göra denna operation i 3D. Kommandot imerode fungerar tyvärr inte för 3D. Istället får man gå direkt på definitionen med faltning. Använd först kommandot convn och sedan kommandot ==. Inbild och utbild ska vara lika stora så använd parametern same. 5
2 4 original image 2 4.5 2 4 eroded image 2 4.5 Figur 4: a) Binär bild. b) Efter krympning (erosion) av två lager pixlar. Kommandot == kan användas så här: Antag att du har en matris i inimage som där du vill söka efter värdet 5. Exekvera: outimagelogical = (inimage == 5); outimage = double(outimagelogical); I outimage hamnar då en matris som har värdet där inimage hade värdet 5. Klassen (class) på outimagelogical är logical medan klassen på outimage är double. Testa detta så att du får exakt samma bild som för imerode. Vad ger du för kommandon? Vi ska nu etikettera bilden. Använd nedanstående Matlabkommandon då de fungerar även för 3D. Resultatet visas i Fig. 5. temp = bwconncomp(cvlerode); CVLlabel = labelmatrix(temp); 2 4 labelled image 2 4 3 2 Figur 5: Etiketterad bild. 6
Bokstaven C (se Fig. 6a) fås enkelt ur den etiketterade bilden i Fig. 5, genom att utnyttja något som ni lärde er på förra sidan. Ge kommandot! 2 4 only C 2 4.5 2 4 noisy C 2 4 5 Figur 6: a) En binär bild av bokstaven C. b) En brusig bild av bokstaven C. 3.5 CV-beräkning innanför ett område Slutligen ska vi beräkna CV-värdet i en brusig boktav C, see Fig. 6b. (Detta kommer vi sedan att göra på SPECT-labben inom ett område där lungan finns på en SPECT-volym av bröstkorgen.) Skapa Fig. 6b genom att kombiera Fig. 2a med Fig. 6a. Ge kommandot för att skapa innehållet i Fig. 6b nedan! Medelvärdet och standardavvikelsen kommer att kunna beräknas nästan på samma sätt som i avsnitt 3.2 och avsnitt 3.3, men antalet pixlar som används för att för att uppskatta dessa värden kommer att variera med positionen. Börja med medelvärdet. Skapa nedanstående variabler (kernelsize och kernel har du nog sedan tidigare): kernelsize = 5; kernel = ones(kernelsize,kernelsize)/(kernelsize^2); Norig = (kernelsize^2); % Norig = 225 ones255 = ones(kernelsize,kernelsize); % matris med 5*5 :or Skapa Fig. 7a genom att falta Fig. 6a med ones255. Skapa Fig. 7b, genom att falta det brusiga C:et med kernel. Varför blir inte resultatet i Fig. 7b det önskade lokala medelvärdet innanför det brusiga C:et? 7
Nu kan ni fortsätta att skapa Fig. 7c. Vad är det korrekta medelvärdet och överensstämmer det med Fig. 7c? a) onlyc conv with ones225 b) noisyc conv with kernel 2 4 2 4 c) Norig * figure b)./ figure a) 2 5 5 2 4 2 4 5 2 4 2 4 5 Figur 7: a) Nnew. b) Lokalt medelvärde av den brusiga C-bilden. c) Norig * figur b./ figur a, dvs korrigerat lokalt medelvärde av det brusiga C:et. Det ni har beräknat nu, i varje pixel, är faktiskt (jämför nedanstående rutor med Fig. 7.): N new m orig = Norig N orig n= f n m new = Nnew N new n= f n Vi har alltså kompenserat för att vi har färre pixlar (N new ) för beräkning av stickprovsmedelvärdet när vi är nära kanten på bokstaven C. Då kan ni fortsätta på samma sätt med standardavvikelsen. Skapa Fig. 8a, genom att falta det brusiga C:et upphöjt till 2 med kernel. Skapa Fig. 8b, Fig. 8c och slutligen Fig. 8d. Det gäller att fact = Nnew./(Nnew-); Det ni har beräknat nu, i varje pixel, är faktiskt (jämför nedanstående rutor med Fig. 8.): 8
N orig Norig n= f 2 n N new Nnew n= f 2 n (m new ) 2 s new = ( N new (N new ) Nnew N new n= f n 2 ( N new Nnew n= f 2 n (m new ) 2) Vi har alltså kompenserat för att vi har färre pixlar (N new ) för beräkning av stickprovsstandardavikelsen när vi är nära kanten på bokstaven C. a) noisyc 2 conv with kernel b) Norig * figure a)./ figure 7a) 2 4 2 4 c) figure b) (figure 7c) 2 5 2 4 2 4 d) real(sqrt(fact.*figure c)) 5 2 4 2 4 5 2 4 2 4 5 Figur 8: a) Lokalt medelvärde av den brusiga C-bilden upphöjt till 2. b) Norig * figur a./ figur 7a, dvs korrigerat lokalt medelvärde av det brusiga C:et upphöjt till 2. c) figur b - (figur 7c upphöjt till 2). d) real(sqrt(fact.*figur c)), dvs korrigerad standardavvikelse av det brusiga C:et. Angående Fig. 8d: Vi tar real eftersom det kan bli negativa värden längs kanterna på Fig. 8c. Drar man roten ur ett negativt tal får man imaginära värden. Vad är den korrekta standardavvikelsen och överensstämmer den med Fig. 8d? Visa bilden på standardavvikelsen för läraren. Blev hen nöjd? Då kan ni fortsätta med att beräkna CV. Kontrollera att din bild liknar Fig. 9a. Ta också fram Fig. 9b och visa sedan för läraren. Blev hen nöjd? I så fall - spara dessa kommandon inför SPECT-labben! 9
2 4 CV 2 4.5 2 4 CV within C 2 4.5 Figur 9: a) CV-beräkning. b) CV-beräkning innanför det brusiga C:et.