使用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()
这里的橙色是使用输出的去卷积和模糊处理恢复的输入信号。
我对此有一些疑问:
我已经附加了用于生成两条曲线的脚本,即物理空间中的原始输入和恢复的输入。
干杯, 凯文
编辑:我应该补充一点,使用scipy.deconvolve +一些小的编辑即可恢复图像。这一定意味着我的方法在某种程度上是错误的?
答案 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的情况下,可以将这种滤波器设计为最小化去卷积信号的均方误差。但是,它需要对信号和噪声的功率谱密度进行一些假设。