Zapisz jako PDF

Transkrypt

Zapisz jako PDF
powrót do strony głównej wykładu Obrazowanie Medyczne
Ćwiczenia z Obrazowania medycznego z
wykorzystaniem programu ImageJ
Otwórz program ImageJ.
1. Rozdzielczość
Wykonaj fantom do analizy rozdzielczości. Na przykład taki:
W tym celu
1. utwórz nowy obraz: File->New->Image i podaj jego rozmiary 128 x 128 punktów.
2. wejdź do okna Process->Math->Macro i wpisz w linijce: v=128*sin(2*PI/32*x)+128. Jak
widzisz takie funkcje jak sinus lub taka wielkość jak PI są w programie predefiniowane.(np.
potęgę trzecią osiąga się funkcją pow(x,3), a pierwiastek sqrt(x) itp.)
3. zapisz obraz we własnym katalogu
Zastanów się jak
1. zmienić częstość przestrzenną fantomu. Stwórz i zapisz dwa inne fantomy o większej częstości.
2. utworzyć fantom o symetrii kołowej, na przykład taki:
3. utworzyć fantom o zmiennej częstości, na przykład taki:
Aby utworzyć fantom zawierający funkcję schodkową (a nie sinusoidalną) proponuję wykonać własne
makro.
1. wybierz Plugins->New->Macro
2. skopiuj poniższy skrypt
3. uruchom makro w okienku edytora: Macros->Run macro (ctrl+R)
//to jest komentarz. Poniżej znajduje się zawartość makra tworzacego fantom z
funkcją schodkową
imax=512;
jmax=512;
T=32;
newImage ("rozdzielczosc", "8-bit black", imax, jmax, 1);
for (i=; i<imax; i++)
for (j=; j<jmax; j++) {
if (i%T<T/2)
setPixel(i, j, 255);
else
setPixel(i, j, );
}
Jeśli chcesz obejrzeć profil jakiejś części fantomu, możesz zaznaczyć obszar i wybrać Analyze->Plot
profile (ctr+K). Jest możliwe obejrzeć też profil wzdłuż linii, jeśli taką się zaznaczy na obrazie.
1. Zaobserwuj jak wpłynie na rozdzielczość dodanie szumu do każdego z tych fantomów:
Process->Noise->Add noise.
2. Wykonaj analizę FFT fantomów: Process->FFT->FFT. Pomnóż uzyskany obraz przez funkcję,
która usunie niskie częstości lub wysokie częstości i wykonaj odwrotną transformację Fouriera:
Process->FFT->Inverse FFT.
Np. pomnożenie przez dwuwymiarową funkcję Gaussa można wykonać tak: v=v*exp(-(pow(64x,2)+pow(64-y,2))/100)
Filtrowanie za pomocą splotu
1.
2.
3.
4.
utwórz nowy obraz o wymiarach 15 x 15
wypełnij go funkcją Gaussa, np. v=exp(-pow(d,2)/10)*255
zamień obraz na liczby: Image->Transform->Image to results
skopiuj całą tabelę (zaznacz w opcjach okienka wyników Results->Options, by nie kopiować
nagłówków kolumn i wierszy)
5. wróć do obrazka z fantomem
6. wybierz Process->Filters->Convolve i wklej tam zawartość swojego Gaussa
2. Sinogram i algorytm wstecznej projekcji
Poniżej zawartość dwóch makr. Pierwsze tworzy sinogram z istniejącego obrazu. Drugie tworzy
rekonstrukcję z sinogramu. W międzyczasie można dokonać filtrowania sinogramu.
Filtrowanie polega na usunięciu z sinogramu niskich częstości poprzez:
1. wykonanie szybkiej transformaty Fouriera (FFT) sinogramu
2. pomnożenie transformaty przez funkcję
, gdzie jest poziomą częstością przestrzenną z
przedziału
3. wykonanie odwrotnej transformaty Fouriera (Inverse FFT).
Zadaniem będzie popracować z paroma różnymi fantomami (jednym z nich będzie fantom SheppaLogana). Najlepiej zacząć pracę z niewielkim fantomem, dla którego szybko pójdą obliczenia.
Zakłada się, że każdy fantom jest obrazem w skali szarości.
Pożądanym wynikiem powinno być automatyczne zapisanie 10 rekonstrukcji dla różnej ilości
projekcji (powinien to zrobić komputer, nie chodzi o robienie każdej rekonstrukcji osobno i ręczne jej
zapisanie). Jeśli to się komuś uda, znaczy, że zrozumiał jak pisać makra w ImageJ. Pod tym adresem
można znaleźć help.
macro "sinogram" {
imax=getWidth();
jmax=getHeight();
kmax=360;
a=floor(sqrt(imax*imax+jmax*jmax)+1);
d_fi=2*PI/kmax;
sinogram=newArray(kmax*a);
for (i=; i<kmax*a; i++)
sinogram[i]=;
for (k=; k<kmax; k++) {
fi=k*d_fi;
x0=-a/2*cos(fi);
y0=a/2*sin(fi);
for (i=; i<imax; i++)
for (j=; j<jmax; j++) {
l=(i-imax/2-x0)*cos(fi)-(j-jmax/2-y0)*sin(fi);
sinogram[k*a+floor(l)]+=getPixel(i,j);
}
}
maks=;
for (i=; i<kmax*a; i++)
maks=maxOf(sinogram[i],maks);
razy=(256*256-1)/maks;
newImage("Sinogram","16-bit",a,kmax,);
for (k=; k<kmax; k++)
for (i=; i<a; i++) {
setPixel(i, k, sinogram[k*a+i]*razy);
}
}
macro "rekonstrukcja" {
a=getWidth();
kmax=getHeight();
imax=floor(a*sqrt(2)/2);
jmax=imax;
a=floor(sqrt(imax*imax+jmax*jmax)+1);
d_fi=2*PI/kmax;
rekon=newArray(imax*jmax);
for (i=; i<imax*jmax; i++)
rekon[i]=;
for (k=; k<kmax; k++) {
fi=k*d_fi;
x0=-a/2*cos(fi);
y0=a/2*sin(fi);
for (i=; i<imax; i++)
for (j=; j<jmax; j++) {
l=(i-imax/2-x0)*cos(fi)-(j-jmax/2-y0)*sin(fi);
rekon[i+j*imax]+=getPixel(floor(l),k);
}
}
maks2=;
for (i=; i<imax*jmax; i++)
maks2=maxOf(rekon[i],maks2);
razy2=(256*256-1)/maks2;
newImage("Rekonstrukcja "+kmax+" projekcji","16-bit",imax,jmax,);
for (i=; i<imax; i++)
for (j=; j<jmax; j++) {
setPixel(i,j,rekon[i+j*imax]*razy2);
}
}