首先,我为 Shepp-Logan 体模在 360 度角下生成正弦图。行方向为沿视图,列方向为沿探测器通道。
from skimage.data import shepp_logan_phantom
from skimage.transform import radon, iradon
SheppLogan = shepp_logan_phantom()
angles = np.arange(0, 360, 1)
sinogram = radon(SheppLogan, angles).T # shape: (360, 400)
然后,我根据众所周知的形式生成 Ramp Kernel(Ram-Lak 滤波器):
1/4 n = 0
0 n even
-1/(pi*n)^2 n odd
带代码
def generateRampKernel(N):
res = np.zeros(N)
center = N // 2 - 1
for i in range(N):
if (i - center) % 2 != 0:
res[i] = -1 / (PI * (i - center)) ** 2
res[center] = 1 / 4
return res
RampKernel = generateRampKernel(400) # A 400 dots Ramp Kernel
此处,Ramp Kernel 的中心位于检测器的中心。(我不知道这是否正确,或者我应该设置center = 0
)。
之后,我对每个视图沿检测器执行 Ramp Kernel 过滤:
for row in range(360):
filteredSinogram[row, :] = np.convolve(sinogram[row, :], RampKernel)[798//2 - 200 : 798//2 + 200]
由于长度为 N 和 M 的两个信号有长度为 N+M-1 的卷积结果,这里我挑出中间的 400 个结果。(我也不知道这是否正确。)
最后,我使用iradon
没有内置过滤器来重构:
recon = iradon(filteredSinogram.T, angles, filter_name=None)
plt.figure(); plt.imshow(recon, cmap='gray')
但是重建图像的值是 Shepp-Logan 幻象的真实值的一半,这意味着我应该将重建图像乘以 2 以获得正确的结果。
为什么?我在哪一步错了?