Önálló laboratórium beszámoló Képfeldolgozáson alapuló orvosi diagnosztikai eljárások kidolgozása Készítette: Forró Márton Miklós Konzulens: Horváth Gábor 2012-13 2. félév
Bevezetés A félév során a cél a tanszéki orvosi képfeldolgozással kapcsolatos tevékenységekbe való bekapcsolódás volt. Ennek eléréséhez szükséges volt a képfeldolgozási alapismeretek megismerése, algoritmusok elsajátítása - majd ezek alkalmazása valós képeken. A tanszéki projekt fókuszában mellkasröntgenek elemzése áll, ezen belül hosszú távú célja káros elváltozások felismerése. A félév második felétől használt szeletképeken a tárgy keretében a tüdőterület belsejét nem tanulmányoztuk. A félév során a végső feladat kialakulása előtt foglalkoztunk a képfeldolgozási ismeretek ránk vonatkozó részével, valamint a független komponens analízis elméleti alapjaival és egy implementációjával. Ez a beszámoló elsősorban a végleges feladat megoldásáról szól, és szintén röviden értekezik a fenti témák megismeréséről, ezek szerint tagolva, a tárgy időrendjében haladva.
Képfeldolgozási alapismeretek A labor első heteiben célunk a szükséges képfeldolgozási algoritmusok megismerése volt. Ezek később a szakirányos Ipari képfeldolgozás és képmegjelenítés c. tárgyból ismertetésre kerültek, viszont azok implementációja és gyakorlati alkalmazása nem része anyagának. Az alapismereteink forrása a Digital Image Processing (Pratt) című könyv volt. A feldolgozott témák az éldetektálás, szegmentálás és morfológiai műveletek voltak, melyek közül rám a morfológia bemutatása esett. Ezen témák feldolgozása adta meg a kezdő MATLAB Image Toolbox ismereteket, amelyekből a félév során kiindultam. Lent látható a kísérletezés egy eredménye. Ekkor elsősorban a témához nem kapcsolódó képeken próbáltuk ki a megismert módszereket. Az alapismeretek bemutatása után kaptunk hozzáférést a tanszéki szerverhez, és így a rajta lévő hagyományos mellkasröntgen-felvételekhez. 1. ábra: Szürkeárnyalatos kép (bal) Morfológiai algoritmusokkal készített kontúrkép (jobb)
Tomoszintézis szeletképek A képfeldolgozási alapok megismerése után áttértünk a tomoszintézissel előállított képek vizsgálatára. A tomoszintézis a számítógépes tomográfiához (CT) hasonló módszer: különböző szögekből készít röntgenképeket a vizsgálat alanyáról. Viszont a CT-től eltérően a felvételt készítő szerkezet nem tesz teljes kört a mellkas körül - míg a CT a test roll Euler-tengelye körül fordul, a tomoszintézis a pitch körül tesz egy korlátozott szögben. Ez a vizsgálat a CT-nél jelentősen kisebb sugárterheléssel jár (kisebbel, mint egy hagyományos mellkasröntgen), és jóval kevésbe költséges a CT-nél, amely lehetőve tesz szűrővizsgálatként való használatát. Hátránya a CT-hez képest, hogy az készített képek kisebb száma és a gyengébb röntgensugár használata csökkenti a kapott képek minőségét. 2. ábra: tomoszintézis felvételek módszere Az elkészült felvételekből matematikai módszerekkel visszaállíthatóak a mellkas szeletei. A visszaállított képek minősége függ a mélységtől a szélsőségeken gyengébb, mivel azok kevesebb szeletből vannak visszaállítva. A visszaállított kép mélységétől függően természetesen a tartalmuk is eltér: bizonyos szinteken a légcső, főhörgők és a szív láthatók, míg másokon a bordák dominálnak. A gerincoszlop is sok képen megjelenik, esetünkben zavaró tényezőként. Az általunk megkapott képek ezen kívül tartalmaztak egy változó szélességű méretű szürke csíkot jobb és bal széleiken.
3, 4, 5. ábra A 3. ábrán (bal fent) látszik, hogy a visszaállított képsorozat szélén található gyengék a kontúrjai, és részleteket szinte egyáltalán nem lehet megfigyelni rajta. A 4. ábrán (jobb fent) a tüdő éles körvonala, a gerincoszlop és szív halványan látszanak. Az 5. ábrán (lent) a szív, a tüdő érhálózata és a légcső látszik. Kitérő: független komponens analízis A szeletképek megkapását követően foglalkoztunk az Independent Component Analysis (ICA független komponens analízis) módszerrel, annak esetleges felhasználhatóságát vizsgálva. Ennek keretében egy-egy konkrét implementációját vizsgáltuk. Az általam kipróbált implementáció a Riken kutatóközpontban Cichocki csapata által fejlesztett ICALAB nevű Matlab toolbox képekre használható változat volt.
Az eszköz több kép eltérő arányokban és módszerekkel összekevert változatából kísérelte meg visszaállítani az eredeti képeket. Az algoritmus futtatása és eredménye saját forrású képekkel (nem a program saját benchmark-ja) első látásra jónak tűntek, de szeletképekre a módszer esetleges hasznát még nem találtuk meg. 6. ábra: kevert kép 7. ábra: ICALAB által visszaállított kép A független komponens alapú megközelítés az ICA alapú éldetektálás témájában később ismét felmerült. A jövőben ennek alkalmazhatóságának vizsgálata hasznos lehet. Tüdőkörvonal megállapítása szeletképeken A félév folyamán kialakult feladatom a tomoszintézissel előállított szeletképeken a tüdő körvonalának meghatározása/tüdőterületet lefedő maszk előállítása volt. A megoldási folyamatom kerete a képfeldolgozás során szokásos szűrés szegmentálás folyamat mellett a régiók megfelelő egyesítését tartalmazza. A megoldásomat először a részeredmény képeken mutatom meg, majd a Matlab kóddal. Az eredeti képek 512x512 pixel méretűek, PNG formátumúak 8. ábra: eredeti kép
Mivel itt körvonalat keresünk, és a képet szegmentálni akarjuk, célszerű a képet megszűrni, ebben az esetben egy Gauss-szűrővel. Ezzel a következő lépésben kapott szegmentáció eredménye jóval kevesebb kis régiót tartalmaz. Fontos, hogy túl erősen elkenő szűrést ne alkalmazzunk, mivel az a nehezebben detektálható kontúrokat (pl. tüdőcsúcs) túlságosan elmoshatja. Mediánszűrő használatával szintén próbálkoztam, ezzel a kapott eredmény minőségbeli különbséget nem mutatott. Végül egy 5x5 pixel méretű Gauss-szűrő használata mellett döntöttem. 9. ábra: szűrt kép Ezután a képet k-means algoritmussal 3 régióra szegmentálom. Ezzel a képet felosztom egy külső és két tüdőn belüli részre (10. ábra). A sárga rész a tüdőterület durva körvonalát fogja adni, a világoskék pedig a tüdőcsúcs és rekeszív pontos körvonalait. A sötétkék régió a szív és a gerincoszlop körülhatárolásában lehetne hasznos, ezek azonban nem voltak részei a feladatomnak. A kapott régiók elég jól közelítik a keresett képterületeket, hogy morfológiai műveletek után használhatóak legyenek. Elsőként meghatározom a tüdő durva körvonalát, amelyet később kiegészítek a megfelelő részletekkel. Ehhez a belső (sárga) régió körvonalát használom fel. Ezen terület alapú zárás 10. ábra: szegmentált kép kívánt eredmény érdekében 11. ábra: tisztított belső körvonal ezen szakaszok eldobása után ismét egy dilate - thin műveletkombinációval megkapom a keresett belső körvonalat. műveletet hajtok végre, ami eltűnteti a kis területű zárványokat. Ezután egy dilatációval a kényszeresen összekötöm a képen a zajos körvonalakat, ezzel a cakkosságuk is megszűnik. A kapott képet visszafogyasztom (morfológiai thin művelet idempotencáig), így megkapom az eddigi élek lesimított változatát. Erről a képről még a kép széleiből adódó hosszú élet, és több rövidet el kell távolítani a 12. ábra: kiinduló körvonal
Tüdőcsúcs A folyamat következő lépése a tüdőcsúcshoz tartozó élszegmens hozzáadása a kiinduló területhez. Ehhez szükséges a felső terület kiválasztása és kitöltése (ez pl. súlypont vagy méret alapján történhet), a kiinduló területtel összenövesztése, az eredő maszkon a lyukak kitöltése majd ebből a nem kilógó terület hozzáadása a kiinduláshoz. A folyamat itt látható: 13. ábra: határok 14. ábra: összenövesztendő területek 15. ábra: különbség Az így kapott körvonal a tüdőcsúcsot jól közelíti. Itt érdemes megjegyezni, hogy a képsorozat egyes képei nem alkalmasak a körvonal minden részének precíz meghatározására. Ezen a képen a tüdőcsúcs nagy pontosságal körülhatárolható, viszont a rekeszív széleinél a kontúrok életlenek, így annak meghatározására, illetve a folyamat általánosítására más módszert kell használni. Rekeszív 16. ábra: eredő körvonal A rekeszív meghatározásának folyamata a tüdőcsúcshoz hasonlóan történik. Azonban a sarkoknál a határ pontatlanságából adódóan, gyakorlati megfontolásból inkább beleveszem a rekeszizom körüli területet is. Ezen a jövőben javítani tervezek. Lejjebb látható a terület, amellyel bővül az eddigi, és a végleges körvonal.
17. ábra: hozzáadott terület 28. ábra: eredmény körvonal Matlab kód %% Előfeldolgozás, szegmentálás I=im2double(imread('File000048.png')); %kép betöltése G=fspecial('gaussian',5,5); Ig=imfilter(I,G); %Gauss-szűrés [g2,c]=kmeans(ig(:),3); %k-means futtatása J22=reshape(g2,size(I)); [A, idx]=sort(c, 'descend'); %középpont szerinti rendezés in=(j22==idx(3)) %belső - legkisebb out=(j22==idx(1)) %külső - legnagyobb %% Belső terület i2=bwareaopen(bwperim(in),100); %tisztítás i3=imdilate(i2,strel('disk',15)); %összenövesztés i4=bwmorph(i3,'thin',inf); %vissza vékonyítás i5=bwmorph(i4,'spur',inf); %végek levágása i6=i5&(~bwmorph(i5,'branchpoints')); %elágazási pontok levágása i7=bwareaopen(i6,70); %tisztítás %legnagyobb levágása CC=bwconncomp(i7); numpixels = cellfun(@numel,cc.pixelidxlist); [a, idx]=sort(numpixels(:),'descend'); i7(cc.pixelidxlist{idx(1)})=0; %élek simítása i8=imdilate(i7, strel('disk',35)); i9=bwmorph(i8,'thin',inf); i10=bwmorph(i9,'spur',inf); %% Tüdőcsúcs o2=bwareaopen(bwperim(out),100); % Méret szerint rendezzük a komponenseket CC=bwconncomp(o2); numpixels = cellfun(@numel,cc.pixelidxlist); [a, idx]=sort(numpixels(:),'descend');
%init top=zeros(512); bot=zeros(512); % Legnagyobb a lenti, második a fenti bot(cc.pixelidxlist{idx(1)})=1; top(cc.pixelidxlist{idx(2)})=1; t2=imfill(top,'holes'); %kitöltés t3=t2 imfill(i10,'holes'); %egyesítés % A fenti és középső részt dilatáljuk (összekötjük), majd % a köztes részt kitöltjük. Az így kapott területet hozzáadjuk % az eredeti tüdőterülethez. t4=imfill(imerode(imdilate(t3,strel('disk',2)),... strel('disk',2)),'holes')&(~t2)&(~t3); t5=bwperim(t4 imfill(i10,'holes')) t6=bwareaopen(t5,50); %% Rekeszív % Összekötés b2=imfill(bot,'holes'); b3=b2 imfill(i10,'holes'); b4=imfill(imerode(imdilate(b3,strel('disk',10)),... strel('disk',10)),'holes')&(~b2)&(~b3); b5=bwperim(b4 imfill(t6,'holes')); b6=bwareaopen(b5,50); % Sarkok b7=imfill(b6,'holes'); b8=imdilate(b7,strel('disk',30))&imdilate(imfill(bot,'holes'),... strel('disk',30)); b9=b8&(~b2); b10=bwperim(imfill((b9 t6),'holes'));