确定性傅立叶反卷积

时间:2019-02-24 23:08:21

标签: python numpy

使用numpy进行傅里叶反卷积时遇到了一些麻烦。我目前正在以3个高斯人的测试用例进行尝试,所以我确切地知道在每一端都有什么期望。

我要恢复的是给定滤波器和输出的确切形式的输入信号。

在这里,我使用了幼稚的约束来抑制将其设置为零的高频端(因为信号在傅立叶空间中也都是高斯分布)。由于这种限制,我希望能以很小的振铃恢复我的原始输入。

#Dummy Case for Gaussian convolve with Gaussian

N = 128
x = np.arange(-5, 5, 10./(2 * N))
epsilon = 1e-18

def gaus(x,sigma):
    return 1./np.sqrt(2*np.pi)/sigma * np.exp(-(x * x)/(2 * sigma**2))

y_g = gaus(x,0.3)     #output gaussian blurred signal
y_b = gaus(x,0.1)     #gaussian blur filter
y_i = gaus(x,np.sqrt(0.3**2 - 0.1**2))   #og gaussian input

f_yg = np.fft.fft(y_g)    #fft the blur
f_yb = np.fft.fft(y_b)    #fft the filter
f_yi = np.fft.fft(y_i)

r_f = (np.fft.fftshift(f_yg)+epsilon)/(np.fft.fftshift(f_yb)+epsilon)      #deconvolve by division in fourier space
r_f[np.abs(x)>0.5] = 0    #naive constraint to remove the artifacts by knowing final form is gaussian

r_f = np.fft.ifftshift(r_f)

r_if = np.fft.ifft(r_f)
y_gf = np.fft.ifft(f_yg)
y_bf = np.fft.ifft(f_yb)
y_if = np.fft.ifft(f_yi)

plt.plot(x,y_if, label='fft true input')
plt.plot(x,r_if, label='fft recv. input')
plt.legend(framealpha=0.)
plt.show()

gaussian

这里的橙色是使用输出的去卷积和模糊处理恢复的输入信号。

我对此有一些疑问:

  1. 显然存在扩展问题。我可以认为这可能会出现的唯一领域是当我应用幼稚的约束时。我是否应该在此步骤中重新归一化,知道我的傅立叶空间上的1 / sqrt(N)*积分等于1?
  2. 看起来恢复的高斯的位置被曲线两侧的一半曲线弄乱了。这是由于傅立叶空间的分裂造成的吗?如何恢复原来的位置(或者一开始我完全做错了此事)

我已经附加了用于生成两条曲线的脚本,即物理空间中的原始输入和恢复的输入。

干杯, 凯文

编辑:我应该补充一点,使用scipy.deconvolve +一些小的编辑即可恢复图像。这一定意味着我的方法在某种程度上是错误的?

1 个答案:

答案 0 :(得分:1)

1)如您所正确理解的那样,缩放的要求与离散傅立叶变换有关。最好的方法是计算两个统一单位信号的反卷积。它们的DFT为n 0 0 0 ....,其中n是DFT的点数。因此,比率r_f为1 0 0 0 0,由np.fft.ifft()计算的后向fft为1 / n 1 / n 1 / n ... 反卷积产生的正确信号应为1 / T 1 / T 1 / T ...,其中T = 10。是帧的长度。

因此,执行反卷积的正确缩放比例为n/T= len(r_f)/10.

r_if=r_if*len(r_if)/10.

2)去卷积信号被转换半个周期。这是由于高斯核位于帧中间的事实。只需将内核移动半个周期即可解决问题。函数np.fft.fftshift()可以用于此目的:

f_yb = np.fft.fft(np.fft.fftshift(y_b))    #fft the filter

编辑:要研究翻译的原因,让我们集中讨论反卷积核是非常窄的高斯分布,几乎对应于Dirac分布的情况。您的输入信号是一个高斯曲线,以零为中心,该帧在-5和5之间采样。类似地,反卷积核是一个以零为中心的Dirac。结果,去卷积信号必须与输入信号相同:以零为中心的高斯曲线。尽管如此,在FFTW中实现的DFT并因此np.fft.fft() is computed as that of a frame starting at 0 and ending at 10在点10j / n处采样,其中j在[0..n-1]中,傅立叶空间中的频率为k / 10其中k在[0..n / 2,-n / 2 + 1 ..- 1]中。因此,此DFT会将您的信号视为以5为中心的高斯信号,并将反卷积内核视为以5为中心的Dirac。将函数f(t)与以t0为中心的Dirac delta(t-t0)进行卷积就是转换函数f(t-t0)。因此,由np.fft.fft()计算的去卷积的结果是输入信号转换了半个周期。由于在[-5,5]帧中输入信号以0为中心,因此np.fft.fft()计算的输出信号以-5为中心(或由于周期性而等效为5)。 转移内核可以解决我们认为帧为[-5 5]和np.fft.ifft()就像处理[0 10]时的不匹配问题。

滤波器通常被设计用来减少高频噪声的影响。因此对卷积进行去卷积会引起高频噪声的潜在放大。像您一样筛选频率是一个潜在的解决方案。注意,这完全等效于使用特定的滤波器对信号进行卷积!

在断层图像重建的范围内,滤波后的反投影算法需要应用斜坡滤波器,从而大幅增加高频噪声。 Here被提议为Wiener filter:在给定卷积信号的SNR的情况下,可以将这种滤波器设计为最小化去卷积信号的均方误差。但是,它需要对信号和噪声的功率谱密度进行一些假设。