Sinogram w pięć minut: co widzi tomograf, zanim zobaczysz obraz
Co jest w tej macierzy?
Sinogram ma dwie osie o zupełnie różnym znaczeniu. Wiersze to kolejne kąty, pod jakimi lampa i detektor obiegły pacjenta. Kolumny to pozycje poszczególnych detektorów w rzędzie. Wartość w komórce mówi, ile promieniowania ubyło na drodze jednego konkretnego promienia.
Jeden wiersz sinogramu to zatem jedno prześwietlenie z jednego kierunku, takie zwykłe zdjęcie rentgenowskie sprowadzone do linii. Cały sinogram to komplet takich prześwietleń, zwykle od kilkuset do ponad tysiąca, wykonanych dookoła pacjenta.
Skąd wzięła się nazwa sinogram?
Wyobraź sobie w skanowanym przekroju jeden mały, gęsty punkt, na przykład metalową kulkę, leżący poza osią obrotu. Przy kącie zero rzuca cień w jednym miejscu rzędu detektorów. Gdy układ obróci się o kilka stopni, cień przesuwa się w bok. Po pełnym obrocie ślad, który kulka zostawiła w sinogramie, jest sinusoidą.
Stąd nazwa. Każdy obiekt w przekroju wpisuje w sinogram własną sinusoidę: im dalej od środka obrotu, tym większa amplituda. To, co widzisz jako sinogram, to suma wszystkich tych krzywych naraz.
Nie ukrywam, że sama na początku mówiłam o nim sinusogram ze względu na jego kształt.
Nie wierzysz? Zobacz to sam!
import numpy as np
import matplotlib.pyplot as plt
from skimage.data import shepp_logan_phantom
from skimage.transform import radon, iradon, rescale
img = rescale(shepp_logan_phantom(), 0.4, anti_aliasing=False)
angles = np.linspace(0., 180., max(img.shape), endpoint=False)
sinogram = radon(img, theta=angles)
rekonstrukcja = iradon(sinogram, theta=angles, filter_name="ramp")
fig, ax = plt.subplots(1, 3, figsize=(12, 4))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("przekrój")
ax[1].imshow(sinogram, cmap="gray", aspect="auto")
ax[1].set_title("sinogram")
ax[2].imshow(rekonstrukcja, cmap="gray")
ax[2].set_title("rekonstrukcja")
plt.show()
źródło: wykonanie własne
Funkcja radon symuluje pomiar, iradon odtwarza z niego obraz. W starszych wersjach scikit-image parametr nazywa się filter, nie filter_name.
Nazwa nie jest przypadkowa: przejście z obrazu do sinogramu to transformata Radona, opisana w 1917 roku, ponad pół wieku przed pierwszym tomografem.
Aby zobaczyć samą sinusoidę, przepuść przez radon obraz z jednym pikselem:
punkt = np.zeros((128, 128))
punkt[40, 90] = 1 # przesunięcie względem środka
plt.imshow(radon(punkt, theta=np.linspace(0., 180., 180, endpoint=False)),
cmap="gray", aspect="auto")
plt.show()
Przesuń punkt bliżej środka macierzy i zobacz, jak krzywa się spłaszcza.
źródło: wykonanie własne
Dlaczego musisz to wiedzieć, kiedy bierzesz się za obrazowanie medyczne i uczenie maszynowe?
Sinogram to surowe dane pomiarowe, a obraz przekroju to już wynik przetwarzania. Różnica ma praktyczne konsekwencje.
Jeden błędny pomiar w sinogramie nie zostaje w jednym miejscu obrazu. Rekonstrukcja rozprowadza go po całym przekroju jako smugę biegnącą przez cały kadr. To dlatego metalowa proteza potrafi zepsuć obraz daleko od siebie samej.
Zmniejszenie liczby kątów, czyli wierszy sinogramu, oznacza mniejszą dawkę promieniowania dla pacjenta i krótsze badanie. Kosztem są charakterystyczne smugi w rekonstrukcji. Spróbuj w powyższym kodzie wziąć co dziesiąty kąt i porównaj wynik: to w miniaturze problem, nad którym pracuje dziś spora część badań nad rekonstrukcją.
Do sieci neuronowych można podawać jedno albo drugie. Praca na obrazie jest wygodniejsza, bo to zwykła macierz pikseli. Praca na sinogramie jest bliżej pomiaru, więc daje szansę naprawić dane, zanim błąd zdąży się rozlać po całym obrazie.





Komentarze
Prześlij komentarz