Ultraljudslaboration TSBB3 Medicinska Bilder Utvecklad av: Mats Andersson (fd IMT) 4 Uppdaterad av: Maria Magnusson (CVL, ISY) 6 Contents Uppgiften Läsa in RF-data En RF skannstråle och dess fouriertransform Enkel enveloppdetektion Enveloppdetektion med kvadratur Subsampling (nedsampling) Histogramtransformation Skannkonvertering Uppgiften Uppgiften i denna labb är att skapa en Brightness-mode (B-mode) ultraljudsbild från Radio frequency(rf)-data. RF-data är de ekon som detekteras i ultraljudsproben direkt efter att ett pulspaket har skickats ut och kristallerna i proben har kopplats om till att lyssna efter ekon. Fig. Exempel på en B-mode ultraljudsbild av ett hjärta. RF-signalen har samma grundfrekvens som den utskickade pulsen och informationen som vi vill återskapa i bilden återfinns i hur amplituden ändras med tiden (signalens envelopp) när ekon från olika djup i vävnaden detekteras i proben. Amplituden varierar mycket långsammare än RF-signalen men vi måste sampla signalen med minst dubbla RF-frekvensen för att undvika vikningsdistorsion enligt samplingsteoremet. Nästa steg är att detektera enveloppen på signalen som innehåller informationen om hur vävnaden inuti kroppen ser ut. Vi kommer först att göra en
enkelenveloppdetektion med likriktning och lågpassfiltrering. Därefter kommer vi att använda oss av kvadraturfilter. Eftersom enveloppen varierar mycket långsammare än grundtonen i RF-signalen kan vi sedan subsampla utan att förlora någon information. Om vi tittar på bilden som den ser ut nu kommer vi att märka att vi tydligt kan se ställen där vi har stor skillnad i akustisk impedans mellan intilliggande vävnad men där skillnaden är liten är det mycket svårt att uppfatta gränsen mellan olika vävnad. För att göra bilden lättare att tolka behöver vi förstärka små skillnader i signalen. Vi gör en gråskaletransformation av signalen, vilket ger en histogramtransformation. Sista steget mot en färdig bild är att göra en skannkonvertering. Bilden är lagrad i en matris där varje kolumn fysiskt motsvarar bildinnehållet i ett vinkelsegment. För att få en geometriskt korrekt bild så måste vi göra en omsampling från en rektangelformad bildarea till en solfjäderformad. Vi kommer att använda matlabs interp för detta och vi vill göra omsamplingen så att vi vet exakt vilken storlek i mm en pixel har så att vi enkelt kan mäta i bilden. Läsa in RF-data RF-data ligger i filen rfdata.mat som laddas ner från hemsidan: load rfdata; Varje kolumn i matrisen rf innehåller informationen från en skannstråle enligt figuren nedan. Ultraljudsprob Lagrad datas format Stråle Bildområde Sampel Utskickade ultraljudspulser Fig. Skannlinjer insamlade med svepande ultraljud lagras som kolumner i matrisen rf. I matlab kör:
info info.help för att för reda på mer information om RF-data. Alla avstånd anges i meter och vinklar i radianer. Vinklar och koordinat system finns också i figuren nedan. Vinkel till den första skannstrålen ärα och var och en av kolumnerna motsvarar ett vinkelinkrement om deltaalpha α X r Y R Fig. Vinklar, avstånd och koordinatsystem för RF-data Fråga : Skriv ner värdena på alla variablerna med korrekta enheter. Fråga : Vi ser att bilden börjar ett visst avstånd r från proben. Varför tror ni att man inte kan avbilda delar av patienten som befinner sig godtyckligt nära proben? Titta på rf som en gråbild med figure() imagesc(rf), title( RF-data ), colorbar colormap gray 3
RF-data 4 5 5 4 3 5 - - 5-3 3 4 5 6 7 8 9 Notera att imagesc automatiskt skalar om bilden, det mest negativa värdet blir svart och det största vitt. rf har medelvärde och detta motsvarar alltså grått i bilden. Notera också storleken. Om vi visar rf med kvadratiska pixlar blir höjd bredd förhållandet över 3 ggr. -4 En RF skannstråle och dess fouriertransform Vi börjar med att titta på en enskild skannstråle (en kolumn i rf-matrisen): col = ; h = rf(:,col); % h blir en vektor från kolumn col i rf Beräkna Fouriertransformen H av h mha fft. Tänk på att använda fftshift eftersom fft utgår från att origo ligger i början på vektorn. H =... H = abs(h); % amplitudspektrum H = H/max(H); % normalisera map maxvärde f = 3; % MHz N = length(h); faxis = [-N/:N/-]*f/N; % skapa frekvensaxel Plotta skannstrålen och dess amplitudspektrum figure() subplot(), plot(h, b ), grid on title( RF-signal (en skannlinje) [sampel nr] ); subplot() plot(faxis,h, b ), grid on title( RF amplitudspektrum [MHz] ); 4
4 5 RF-signal (en skannlinje) [sampel nr] -5 5 5 5 3 RF amplitudspektrum [MHz].8.6.4. -5 - -5 5 5 Använd horizontal zoom för att studera plotten av h. Fråga 3: Läs av samplingsfrekvens och ungefärlig RF-frekvens i plotten. Stämmer de med de värden ni noterade på Fråga? Fråga 4: I amplitudspektrum ser vi att det finns en liten topp på precis dubbla RF-frekvensen. Vad beror det på? Enkel enveloppdetektion Först ska vi göra en enkel enveloppdetektion. Börja med att helvågslikrikta h (tag absolutbeloppet) följt av lågpass-filtrering. Filtreringen (faltningen) kan göras med funktionen imfilter. För att tillverka ett D lågpass-filter kan man använda fspecial: flp = fspecial( gaussian,[,],) flp =.88.7.65...... som ger ett Gaussiskt LP-filter i y-led med storlek = och standardavvikelse =. Fråga 5: Hur skapar man den likriktade signalen hlikrikt? hlikrikt =... flp = fspecial( gaussian,[,],); h_envelopp = imfilter(hlikrikt, flp, replicate ); 5
figure(3) subplot(,,), plot(h, b ), hold on plot(h_envelopp, r ) title( RF-signal med envelopp [sampel nr] ) grid subplot(,,), plot(hlikrikt, b ), hold on title( efter likriktning och LP-filtrering ), grid plot(h_envelopp, r ) 4 4 RF-signal med envelopp [sampel nr] - -4 4 45 5 55 6 65 7 75 8 4 4 efter likriktning och LP-filtrering - -4 4 45 5 55 6 65 7 75 8 Fråga 6: Zooma horizontellt i plotten. Hur bra är resultatet? Spara undan denna som plot som enkelenvelopp.fig! Enveloppdetektion med kvadratur Vi vill bara behålla den del av spektrat som motsvarar toppen runt RFfrekvensen, övriga delar kommer bara att bidra till ett försämrat signal-tillbrus förhållande (SNR). Signalen behöver bandpassfiltreras med ett bandpass filter där center frekvensen u och bandbredden B är anpassad till signalens spektrum. Vi kommer att använda kvadraturfilter både till att välja ut rätt frekvensband och för att gör envelopp detektering. Först koncentrerar vi oss på frekvensbandet. En mängd olika D kvadraturfilter finns i filen quadraturefilters.mat. Ett kvadraturfilter med namn qfilt_pi_4_b_ har en centerfrekvens (mätt i normaliserad vinkelfrekvens) u = π/4 som svarar mot och en vanlig centerfrekvens f = u f s /(π) Hz och en bandbredd B =. oktaver. En oktav innebär en fördubbling av frekvensen. Bandbredden mäts från 6dB gränsen (dvs när filtrets amplitud har sjunkit till hälften). För ett kvadraturfilter med bandbredd B = innebär det att den övre gränsfrekvensen, u h, är 4ggr så stor som den undre, u l. Vidare gäller att u = u l u h och B = log(u h /u l ). Läs in kvadraturfiltren och välj ut ett filter med lämplig centerfrekvens. Band- 6
bredd B= kan vara lagom. load quadraturefilters.mat whos Fråga 7: Vilket av filtren väljer du? Motivera! f = qfilt_pi_... f =. +.5i. +.6i -.7 +.7i -.37 +.4i...... Som du ser är filtret komplexvärt. Plotta realdel och imaginärdel figure(4) pos = (size(f,)-)/; plot([-pos:pos],real(f), g ),hold on plot([-pos:pos],imag(f), r ),grid on, hold off title( complex valued conv kernel f ).3 complex valued conv kernel f.5..5..5 -.5 -. -.5 -. -5 - -5 5 5 Fråga 8: Vad kan man säga om symmetrin för filtrets real och imaginärdel i termer om jämn och udda? Plotta fouriertransformen av filtret. Vi vill ha samma storlek på Fouriertransformen av filtret som som längden på rf för att kunna jämföra med signalens spektrum H. Vi paddar på nollor före och efter f så att vi får en vektor som är lika lång som rf. Eftersom filtret alltid har en udda storlek och storleken på rf är jämn så behöver vi en nolla mer på den första delen. 7
n = floor((length(rf)-length(f))/); fpad = [zeros(n+,); f; zeros(n,)]; Beräkna Fouriertransformen av den reella delen av filtret först och plotta den tillsammans med amplitud spektrum. Fre = fftshift( fft( ifftshift( real(fpad)))); Fre = real(fre); Fre borde vara reell men mycket små imaginära värden kan finnas. Kolla gärna! Plotta Fre och RF amplitudspektrum i samma plot. figure(5) plot(faxis, H, b ),hold on plot(faxis, Fre, g ), hold off, grid on title( Fouriertransform av real(f) och RF amplitudspektrum [MHz] ) Fouriertransform av real(f) och RF amplitudspektrum [MHz].8.6.4. -. -5 - -5 5 5 Beräkna även fouriertransformen av den imaginära delen av f och hela f och plotta alla tillsammans: Fim = fftshift( fft( fftshift( i*imag(fpad)))); Fim = real(fim); F = fftshift( fft( fftshift(fpad))); F = real(f); figure(6) plot(fre, g ),hold on plot(fim, r ) plot(f, k ), hold off, grid on title( Fouriertransformer av real(f), i*imag(f) och f [MHz] ) 8
Fouriertransformer av real(f), i*imag(f) och f [MHz].5.5 -.5-5 5 5 3 Fråga 9: Vilka symmetrier gäller för real(f), i*imag(f) och dess fouriertransformer? Stämmer det med Figur. i kompendiet? Jämför också med fouriertransformen av cosinus och i*sinus. Nu har vi ett filter f som består av en reell jämn del och en imaginär udda del i tidsdomänen. De har samma amplitudspektrum, men släcker ut varandra i ena halvan av fourierdomänen och samverkar i den andra. Detta är ett säkert kännetecken på ett kvadraturfilter! Nu ska vi titta på vad detta innebär i tidsplanet. Filtrera (falta) rf med f. Vi använder matlabs imfilter för filtreringen. q = imfilter(rf, f, replicate ); Titta på original RF-signalen, samt resultatet efter filtrering. Titta på den reella delen och den imaginära delen i samma figur. figure(7) subplot(), plot(real(rf(:,col)), b ); grid on title( Original RF-signal ) subplot(), plot(real(q(:,col)), g ); hold on plot(imag(q(:,col)), r ); hold off, grid on title( Real and imaginary part of RF-signal filtered with f ) 9
4 Original RF-signal - - 5 3 35 4 45 5 4 Real and imaginary part of RF-signal filtered with f - - 5 3 35 4 45 5 Fråga : Zooma horizontellt i den nedre figuren, så att man kan se att de två komponenterna är fasförskjutna enligt figuren ovan. Vilken fasförskjutning gäller? Zooma även horizontellt i den övre figuren. Påverkades den reella delen mycket eller litet av bandpassfiltreringen? Fråga : Absolutvärdet av dessa två komponenter ska ge enveloppen. Plotta abs(q) ovanpå rf i samma plot Utför horizontell zoomning så att det ser ut ungefär som nedan. Spara undan denna som plot som kvadraturenvelopp.fig! Jämför med enkelenvelopp.fig. Vilken är bäst? figure(8) plot(rf(:,col), b ); hold on q =...... 4 4 RF-signal med envelopp [sampel nr] 3 - - -3-4 4 45 5 55 6 65 7 75 8 Titta på q som en gråskalebild. Jämför med den tidigare bilden av rf i figure() (och på s. 3) figure(9) imagesc(q), title( envelopp av RF-data ), colorbar
colormap gray envelopp av RF-data 4 4 5 3.5 3.5 5.5 5.5 3 4 5 6 7 8 9 Fråga : Vilka skillnader och vilka likheter syns i de två bilderna? Subsampling (nedsampling) Som vi ser bilderna så varierar enveloppen q mycket långsammare än rfsignalen. Vi kan nu subsampla utan att förlora någon information. Vi drar först bort medelvärdet från en skannstråle i q. Medelvärdet innehåller ingen information och dominerar spektrumet q = q(:,col) - mean(q(:,col)); % dra bort medelvärdet Q = fftshift(abs(fft(q))); % amplitudspektrum av q Q = Q/max(Q); figure() plot(faxis,q, b ), grid on title( envelopp amplitudspektrum [MHz] ); envelopp amplitudspektrum [MHz].9.8.7.6.5.4.3.. -5 - -5 5 5 Vi bedömmer att när spektrum har sjunkit till / (4dB) är värdena så små att de inte behövs.
Fråga 3: Vid vilken ungefärlig frekvens har spektrum sjunkit till /? Vilken faktor gäller mellan denna frekvens och maxfrekvensen? Subsampla med denna faktor och använd resample. Observera att vi vill bara subsampla q utmed dess kolumner. Gör help resample för att ta reda på hur det går till. qsub = resample(q,...,...); Titta på resultatet i fourierdomänen. Notera att de högsta frekvenserna har försvunnit. q = qsub(:,col) - mean(qsub(:,col)); % dra bort medelvärdet Q = fftshift(abs(fft(q))); % amplitudspektrum av q Q = Q/max(Q); Nsub = length(qsub); faxissub = [-Nsub/:Nsub/-]*f/length(q); % skapa frekvensaxel figure() plot(faxissub,q, b ), grid on title( subsamplad envelopp amplitudspektrum [MHz] ); subsamplad envelopp amplitudspektrum [MHz].9.8.7.6.5.4.3.. -4-3 - - 3 4 Titta på resultatet som en gråskalebild. figure() imagesc(qsub), title( subsamplad envelopp av RF-data ), colorbar colormap gray
subsamplad envelopp av RF-data 4 4 3.5 3 3.5 4 5.5 6 7.5 3 4 5 6 7 8 9 Fråga 4: Vilken är skillnaden mot tidigare i figure(9)? Histogramtransformation Om vi tittar på bilden av qsub och dess histogram: figure(3) subplot(,,),imagesc(qsub) colormap gray, title( qsub ) subplot(,,) hist(qsub(:),56), title( hist(qsub) ) qsub 45 hist(qsub) 3 4 4 35 3 5 5 5 6 7 4 6 8 5 4 6 4 så ser vi att väldigt många pixlar är nästan svarta och det är bara i områden där vi har stora skillnader i akustisk impedans som vi kan se något av strukturen. Vi behöver förstärka små värden i bilden relativt de större för att få en mer lätt tolkad bild. Idealet är ett bredare, jämnare, gärna klockformat histogram. Att skriva q(:) är ett matlab-trick som drar ut värdena i matrisen q till en vektor. 3
På så sätt får vi ett histogram för hela bilden, annars får vi ett histogram för varje kolumn. Ett mer jämt fördelat histogram fås med figure(4) subplot(,,) hist(log(qsub(:)),56), title( Jämnare histogram, var ) subplot(,,) hist(sqrt(qsub(:)),56), title( Jämnare histogram, var ) 8 Jämnare histogram, var 6 4 3 4 5 6 7 8 9 5 Jämnare histogram, var 5 5 5 5 För att åstadkomma detta måste q gråskaletransformeras genom en funktion som förstärker de små värdena relativt de stora. Prova både qe=sqrt(q) och qe=log(q). Titta på bilden och på histogrammet. qe =... Fråga 5: Vilken gråskaletransformation föredrar du? Det är ganska subjektivt, men motivera ditt val! När du är nöjd med bilden och histogrammet så justerar vi bilden så att värdena ligger mellan och för att lätt kunna spara ner bilden på ett standardformat senare. qe = qe - min(qe(:)); qe = qe / max(qe(:)); figure(5) imagesc(qe),colormap gray title( Bild efter histogramtransformering i området [, ] ) 4
Bild efter histogramtransformering i området [, ] 3 4 5 6 7 3 4 5 6 7 8 9 Skannkonvertering Nu har vi en bild som ser bra ut utom i ett avseende. Bilden är insamlad i polära koordinater, (vinkel, radie), och lagrad i en (kartesisk) matris. När vi tittar på bilden av qe så har hjärtat fel geometri och storleken på objekt i bilden varierar med positionen i bilden. Vi måste sampla om bilden till ett solfjäderformat. Vi använder matlabs interp för detta. Vi kommer att behöva ange 5 inargument som alla är matriser: I = interp(qalpha, qrad, qe, Ialpha, Irad) De tre första argumenten har med indata att göra och qe är vår histogramtranformerade bild. Matriserna qalpha och qrad har samma storlek som qe men anger vilken vinkel resp. radie som varje position motsvarar. Titta återigen på figuren på sidan 3 i början på labpm, som beskriver vinklar och koordinatsystem. Gör info och info.help vid behov. Vi gör först st vektorer som beskriver hur alpha och r varierar i bilden alpha = info.alpha; deltaalpha = info.deltaalpha; nbeams = info.nbeams; alphamax = alpha + deltaalpha*(nbeams-); alphavec = linspace(alpha, alphamax, nbeams); Matlabs linspace genererar en linjär vektor som börjar i alpha och slutar i alphamax med längden nbeams, dvs steglängden (alphamax- alpha)/(nbeams-). Gör en motsvarande vektor för radien. r =... R =... rvec = linspace(...,..., length(qe)); Nu kan vi använda matlabs meshgrid för att generera matriserna qalpha och qrad från vektorerna alphavec och rvec 5
[qalpha, qrad] = meshgrid(alphavec,rvec); Kontrollera att matriserna har samma storlek som qe och att det är regelbundna avstånd mellan rader/kolumner. Det är en förutsättning för att använda interp De två sista argumenten i interp relaterar till de koordinater vi vill ha de nya sampelpunkterna i. Fråga 6: Markera alphamax i figuren på sidan 3 och räkna därefter ut min och max för X och Y koordinaterna. Avståndet ska anges i meter. Ymax = R; Ymin =... Xmax =... Xmin =... Bestäm storleken i meter på en pixel i den geometriskt korrekta bilden. Välj en storlek på mm (. meter) eller mindre. dpix =... Gör en X och en Y vektor Xvec = [Xmin:dpix:Xmax]; Yvec = [Ymin:dpix:Ymax]; Använd sedan meshgrid igen för att få motsvarande matriser med X och Y koordinater i interpolerade bilden. [X,Y] = meshgrid(xvec,yvec); Matriserna X och Y innehåller de kartesiska koordinaterna för den färdiga bilden I men för att vi ska kunna interpolera i originalbilden behöver vi räkna om hur X och Y mappas till de polära koordinaterna i originalbilden. Irad =... Ialpha = atan(y,-x) + pi; Om du har gjort rätt ska Ialpha ha värden mellan π och π och vara störst på högersidan. Titta gärna på Irad och Ialpha som bilder om du är osäker. Interpolera fram den slutgiltiga bilden mha interp. I = interp(qalpha, qrad, qe, Ialpha, Irad); En del koordinater i I hamnar utanför qe. Matlab sätter dessa värden till NaN (Not a Number). Vi sätter dessa värden till och tittar på resultatet. 6
I(isnan(I))=; figure imagesc(i), colormap gray; title( Min B-mode bild ) Min B-mode bild 5 5 5 3 35 4 45 5 5 5 3 35 4 45 Fråga 7: Kontrollera att din bild är lika fin som den som visas här. Visa också bilden för läraren! Om du vill spara din bild i något standard format som t.ex PNG kan du använda imwrite: imwrite(i, mybmodeim.png, PNG ) 7