ฉันได้เล่นกับอัลกอริทึมการสร้างใหม่ tomographic เมื่อเร็ว ๆ นี้ ฉันมีการใช้งานที่ดีของ FBP, ART, รูปแบบการวนซ้ำแบบ SIRT / SART และแม้กระทั่งการใช้พีชคณิตเชิงเส้นแบบตรง (ช้า!) คำถามนี้ไม่เกี่ยวกับการใด ๆ ของเทคนิคเหล่านั้น ; คำตอบของแบบฟอร์ม "ทำไมทุกคนจะทำอย่างนั้นนี่คือรหัส FBP บางส่วนแทน" ไม่ใช่สิ่งที่ฉันกำลังมองหา
สิ่งต่อไปที่ฉันต้องการจะทำกับโปรแกรมนี้คือ " ทำให้ครบชุด " และใช้ " วิธีการสร้างใหม่ฟูเรียร์ " ความเข้าใจของฉันเกี่ยวกับเรื่องนี้เป็นพื้นฐานที่คุณใช้ 1D FFT กับ "การสัมผัส" แบบไซน์จัดเรียงสิ่งเหล่านั้นในรูปแบบ "ซี่ล้อ" ในรัศมี 2D ในพื้นที่ฟูริเยร์ 2D (ซึ่งนี่เป็นสิ่งที่มีประโยชน์ที่ต้องทำดังนี้โดยตรงจาก สอดแทรกจากจุดเหล่านั้นไปยังตารางปกติในพื้นที่ 2D นั้นและจากนั้นควรจะสามารถแปลงฟูริเยร์เพื่อแปลงเป้าหมายสแกนต้นฉบับได้
ฟังดูง่าย แต่ฉันไม่ได้โชคดีเลยที่จะมีไทคอนซึ่งมีลักษณะเหมือนเป้าหมายดั้งเดิม
รหัส Python (numpy / SciPy / Matplotlib) ด้านล่างนี้เกี่ยวกับการแสดงออกที่กระชับที่สุดที่ฉันสามารถหาได้จากสิ่งที่ฉันพยายามจะทำ เมื่อเรียกใช้จะแสดงสิ่งต่อไปนี้:
รูปที่ 1: เป้าหมาย
รูปที่ 2: รูปสัญลักษณ์ของเป้าหมาย
รูปที่ 3: แถว sinogram FFT-ed
รูปที่ 4: แถวบนสุดคือพื้นที่ FFT 2 มิติที่ถูกสอดแทรกจากแถว sinogram ของโดเมนฟูริเยร์ แถวล่างคือ (สำหรับวัตถุประสงค์ในการเปรียบเทียบ) 2D โดยตรง FFT ของเป้าหมาย นี่คือจุดที่ฉันเริ่มสงสัย พล็อตที่ถูกสอดแทรกจาก FFT ของ sinogram นั้นดูคล้ายกับแผนการที่ทำโดย 2D-FFTing โดยตรงกับเป้าหมาย ... และยังแตกต่างกัน
รูปที่ 5: การแปลงผกผัน - ฟูริเยร์ของรูปที่ 4 ฉันหวังว่าสิ่งนี้จะเป็นที่จดจำได้มากกว่าในฐานะที่เป็นเป้าหมายมากกว่าที่เป็นจริง
ความคิดเห็นใดที่ฉันทำผิด ไม่แน่ใจว่าการทำความเข้าใจวิธีการฟื้นฟูฟูริเยร์ของฉันนั้นมีข้อบกพร่องพื้นฐานหรือมีข้อบกพร่องบางอย่างในรหัสของฉัน
import math
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import scipy.interpolate
import scipy.fftpack
import scipy.ndimage.interpolation
S=256 # Size of target, and resolution of Fourier space
A=359 # Number of sinogram exposures
# Construct a simple test target
target=np.zeros((S,S))
target[S/3:2*S/3,S/3:2*S/3]=0.5
target[120:136,100:116]=1.0
plt.figure()
plt.title("Target")
plt.imshow(target)
# Project the sinogram
sinogram=np.array([
np.sum(
scipy.ndimage.interpolation.rotate(
target,a,order=1,reshape=False,mode='constant',cval=0.0
)
,axis=1
) for a in xrange(A)
])
plt.figure()
plt.title("Sinogram")
plt.imshow(sinogram)
# Fourier transform the rows of the sinogram
sinogram_fft_rows=scipy.fftpack.fftshift(
scipy.fftpack.fft(sinogram),
axes=1
)
plt.figure()
plt.subplot(121)
plt.title("Sinogram rows FFT (real)")
plt.imshow(np.real(np.real(sinogram_fft_rows)),vmin=-50,vmax=50)
plt.subplot(122)
plt.title("Sinogram rows FFT (imag)")
plt.imshow(np.real(np.imag(sinogram_fft_rows)),vmin=-50,vmax=50)
# Coordinates of sinogram FFT-ed rows' samples in 2D FFT space
a=(2.0*math.pi/A)*np.arange(A)
r=np.arange(S)-S/2
r,a=np.meshgrid(r,a)
r=r.flatten()
a=a.flatten()
srcx=(S/2)+r*np.cos(a)
srcy=(S/2)+r*np.sin(a)
# Coordinates of regular grid in 2D FFT space
dstx,dsty=np.meshgrid(np.arange(S),np.arange(S))
dstx=dstx.flatten()
dsty=dsty.flatten()
# Let the central slice theorem work its magic!
# Interpolate the 2D Fourier space grid from the transformed sinogram rows
fft2_real=scipy.interpolate.griddata(
(srcy,srcx),
np.real(sinogram_fft_rows).flatten(),
(dsty,dstx),
method='cubic',
fill_value=0.0
).reshape((S,S))
fft2_imag=scipy.interpolate.griddata(
(srcy,srcx),
np.imag(sinogram_fft_rows).flatten(),
(dsty,dstx),
method='cubic',
fill_value=0.0
).reshape((S,S))
plt.figure()
plt.suptitle("FFT2 space")
plt.subplot(221)
plt.title("Recon (real)")
plt.imshow(fft2_real,vmin=-10,vmax=10)
plt.subplot(222)
plt.title("Recon (imag)")
plt.imshow(fft2_imag,vmin=-10,vmax=10)
# Show 2D FFT of target, just for comparison
expected_fft2=scipy.fftpack.fftshift(scipy.fftpack.fft2(target))
plt.subplot(223)
plt.title("Expected (real)")
plt.imshow(np.real(expected_fft2),vmin=-10,vmax=10)
plt.subplot(224)
plt.title("Expected (imag)")
plt.imshow(np.imag(expected_fft2),vmin=-10,vmax=10)
# Transform from 2D Fourier space back to a reconstruction of the target
fft2=scipy.fftpack.ifftshift(fft2_real+1.0j*fft2_imag)
recon=np.real(scipy.fftpack.ifft2(fft2))
plt.figure()
plt.title("Reconstruction")
plt.imshow(recon,vmin=0.0,vmax=1.0)
plt.show()