Nástroj pro kónickou zpětnou projekci Po absolvování předmětu Anlýza signálů a obrazů na VUT Brno (mimochodem s výstižnou zkratkou MASO :-) jsem se nějakou dobu vrtal v problematice zpětné projekce. To je celkem jednoduchý algoritmus, kterým lze z 1D projekcí, např. rentgenových, pořízených z různých úhlů složit 2D řez objektem. Pro jeden řez to fungovalo celkem dobře, ale už tehdy mě docela nahlodávala myšlenka, jestli by šlo provádět zpětnou projekci přímo z 2D projekcí do 3D objemového modelu. Později jsem se dočetl, že se tomuto typu říká kónická zpětná projekce (cone-beam backprojection). Když jsem nedávno zahlédl na Youtube nějaká rentgenová videa rotujících objektů, tak jsem si řekl, že by se to dalo použít jako testovací data a zkusil jsem k tomu účelu napsat rekonstrukční nástroj, který je předmětem následujícího textu. Nejdřív jsem to zkusil v Matlabu, ale bylo to poněkud pomalé, takže jsem se rozhodl procvičit své oblíbené C/C++. Překvapivě se mi povedlo celkem rychle rozchodit obě základní metody (ray/voxel driven algorithm) a výkon byl velmi uspokojivý. Protože exportovat a načítat data do prohlížeče 3D objemových modelů 3D Slicer je poněkud neohrabané a pomalé (a navíc ten SW má řadu buggů/nepříjemných vlastností), implementoval jsem i svůj vlastní raycaster získaného modelu, což je vlastně přímá projekce, tedy přesný opak zpětné projekce a většina algoritmu tak zůstala zcela identická. 1. Nějaká ta teorie Zpětná projekce je velmi jednoduchá metoda. V zásadě jde jen o sečtení 1D projekcí pořízených pod několika úhly do jednoho 2D obrazu. Aby byl výsledek ostrý, je před tím třeba provést filtraci (proto se metoda jmenuje filtrovaná zpětná projekce). K tomuto účelu se používá něco na způsob horní propusti. Tento filtr taky odstraní bias (střední hodnotu jasu celého řezu). Graficky znázorněný princip ukazuje obr. 1.1. Detaily v angličtině [2].
3D model se touto základní technikou získává tak, že se skenovací rám nebo skenovaný objekt postupně posouvá a postupně získané řezy
se pak složí do výsledného 3D objemového modelu, který lze zobrazit např. ve zmíněném 3D Sliceru (dostupný zadarmo).
Vlastní algoritmus je v tomto případě analogický: Virtuální detektor a ohnisko rentgenky se umístí v 3D prostoru přesně tak, jak byly
během skenování, obraz na detektoru se "protáhne" směrem k ohnisku (podobně jako v případě 2D verze na obr. 1.1) a část vzniklého jehlanu, která protíná
rekonstrukční oblast, v tomto případě krychli, se do ní jednoduše přičte. Totéž se opakuje pro všechny dostupné projekce. Nevýhoda je, že jich musí pro čistý obraz být docela
dost, ale ne zase nijak extrémně (na kuře stačilo 45 projekcí na 360° rotaci). 2. Popis vlastního programu Popisovaný program je schopen načíst obrázky projekcí exportované např. ze zmíněných 3D videí, provést filtraci, zpětnou projekci a na konec zobrazit výsledek buďto po řezech nebo pomocí raycasteru (3D).
Program je jako obvykle napsán v BDS 2006 Turbo C++ a byl testován ve Windoze XP/7. Je kompilován jako 32bit aplikace, takže by měl jet jak
v 32bit, tak i 64bit systémech. Program používá pouze základní sadu 586, takže teoreticky jede i na starém železe, ale rozumných výsledků lze dosáhnout jen na moderních
vícejádrových CPU a předevsím s rychlou pamětí! Zatímco mezi výpočetním výkonem v základních instrukcích nebude mezi nějakým 5 let starým Core 2 Duo a Intel i5 valný rozdíl,
paměť udělá při té velikosti polí (stovky MB) skutečně hodně. Konkrétně jsem program ladil na Intel i5 3450 (4 jádra/4 vlákna) s 1600MHz DDR3 pamětí.
Na starším Core 2 Duo s 800MHz DDR2 to v přepočtu na jedno jádro jelo asi čtvrtinovým tempem (docela překvápko). Aby program využil dnešní vícejádrové CPU,
jsou pochopitelně všechny náročnější výpočty distribuované do více vláken. Poprvé jsem
také zcela oddělil výpočty od VCL vlákna (GUI), takže rozhraní by mělo reagovat i během výpočtu a ten tak lze obvykle přerušit. 2.1 Licence Prográmek je freeware, takže může být používán i šířen jak libo, ale bez jakékoliv záruky správné funkce. Distribuce je povolena, ale jen s přiloženou složkou help, tj. tímto helpem! Autor se zříká odpovědnosti za jakoukoliv škodu způsobenou použitím tohoto programu ať už by byla jakákoliv. Použitím programu vyjadřujete souhlas s uvedenými podmínkami, v opačném případě program nepoužívejte. 2.2 Vytváření nového projektu (setup)
K vytvoření nového projektu je třeba někam zkopírovat INI soubor přiloženého příkladu. Lze to buď udělat ručně nebo načtením vzoru a uložením pod jiným názvem.
Následně je třeba ručně vyplnit sekci [PATH] nového INI souboru (projektu). Sekce obsahuje jen dva klíče: 2.3 Nastavení geometrie scény (Scene geomety setup) První věc, co je třeba nastavit pro nový projekt, je geometri scény, tj. vzdálenost rentgenky, rozměry detektoru, úhlový krok skenování apod. Význam použitých nastavení je uveden na obr. 2.2 (červená krychle uprostřed je rekonstrukční oblast, kde vzniká objemový model).
Ofsety du a dv jsou myšleny relativně vzhledem k rozměrům detektoru v rozsahu ±0.5. Výška detektoru se dopočítává automaticky z poměru stran obrázků projekcí. Jakékoliv změny je třeba potvrdit stiskem "Refresh" nebo klávesy Enter. 2.4 Nastavení filtru (Filter) Zde se nastavuje filtrace obrázků projekcí. První filtr v pořadí je práh a saturace v rozsahu 0 až 255, kterou lze odstranit část šumu zdrojových dat. Následuje filtrace okénkovou funkcí, kterou lze odstranit ostré přechody po obvodu projekcí. Poslední filtr je vlastní filtr zpětné projekce. Program umožňuje filtrovat vertikálně i horizontálně, ale obvykle se používá jen horizontální filtrace (u-axis). Standardní nastavení (cosine filter): f=1.0 a s=1.0. Výsledná data po všech filtracích jsou pak normalizovány na nastavenou úroveň (standardně 1024). Při nastavení "common" se všechny projekce berou jako jako jeden obrázek, na něm se provede normalizace a zase se rozseká na jednotlivé projekce. Díky tomu nedojde k vzájemné změně intenzity jednotlivých projekcí. Při nastavení "individual" se každá projekce normalizuje samostatně. To se může hodit pokud je expozice jednotlivých projekcí proměnlivá. Každou změnu je třeba potvrdit stiskem klávesy Enter (stisk Refresh neprovede přepočet filtrů!). Po přepočtu filtrů se spustí nová rekonstrukce. 2.5 Nastavení objemového modelu (Voxel volume)
Prvním nastavením je rozlišení N v rozsahu 64 až 400. Decimace umožňuje vyřadit část projekcí pro urychlení rekonstrukce. Hodí se to při
experimentálním ladění geometrie. Nastavení "Mode" umožňuje měnit metodu rekonstrukce, jak bylo popsáno v teorii. "Ray driven" metoda je obvykle rychlejší, ale hodí se
maximálně pro rychlé experimentální ladění geometrie a filtrů. Kvalitu výstupu za cenu výpočetního času lze zvýšit upsamplingem. Pro finální rekonstrukci je vhodné použít metodu
"Voxel driven". Ta sice zabere více času, ale dává podstatně čistší výsledky. V tomto případě lze alternativně zapnout lineární interpolaci, což se může hodit pro malé
rozlišení projekcí. 2.6 Prohlížeč řezů (Slice viewer) V tomto panelu lze nastavit orinetaci a pozici řezu v objemovém modelu. Pro potlačení šumu jsou k dispozici základní filtry (práh a gamma korekce). Klávesa Esc resetuje trackbary do defaultní polohy. Dvojklik na obrázek řezu nabídne export ve formátu BMP. 2.7 Prohlížeč projekcí (Projections viewer) Tlačítkem "View Projections" lze zobrazit prohlížeč obrázků projekcí. Lze zobrazit originální obrázek a jeho filtrovanou variantu.
2.8 Raycaster objemového modelu (Volume raycaster)
Protože používat 3D Slicer je celkem o nervy, implementoval jsem svůj vlastní raycaster. Má sice jen pár základních funkcí, ale rozhodně
je jeho použití efektivnější, než po každé změně nastavení exportovat data, načítat je do 3D Sliceru a znovu ho nastavovat
(ukládání projektu v 3D Sliceru v současné verzi jaksi nefunguje - vytuhne to).
Raycaster vyžaduje provést pár ručních nastavení. Ty jsou rozděleny do několika záložek a jsou uspořádány tak, jak jsou během vlastního
výpočtu používány. Nejdůležitějším nastavením je práh, pomocí kterého je třeba odstranit šum okolo modelu. Dále je k dispozici nastavení "cutoff", které pro změnu umožňuje
zahodit voxely přesahující nastavenou hodnotu.
Poslední záložka slouží k nastavení post-filtrace. Jako obvykle je k dispozici gamma a negativní režim. Především je ale k dispozici možnost omezit úroveň saturace (bíla barva). Raycaster si standardně nastavuje úroveň bílé sám, ale lze mu vnutit vlastní hodnotu. Při zaškrtlém nastavení "Fixed" bude úroveň bíle nastavena na zadanou hodnotu i v prípadě, že skutečná úroveň bílé je nižší (to může také vést k tomu, že celý obraz bude černý, takže na toto nastavení nezapomínat). 3. Ukázkové datové soubory Zde je pár již exportovaných a nakonfigurovaných datových souborů:
4. Zdroje Vzhledem k tomu, že jsem byl tentokrát líný kreslit všechno sám, použil jsem cizí obrázky z níže uvedených zdrojů. Ty také obsahují podstatně více teorie, kdyby se tím někdo chtěl zabývat:
Zdrojová data pro ladění programu jsem získal z 3D rentgenových videí na Youtube. Našel jsem zatím tyto autory:
Jeden příklad zdrojových videí za všechny [5]: (c) 2013-2018, Stanislav Mašláň - Všechna práva vyhrazena.
|