繁体   English   中英

如何使用 FFT 通过 python 找到卷积 function?

[英]How can I use FFT to find convolution function by python?

我有 output 和一个系统的输入,据我所知 f=conv(h,g),h 是 FFT 中的卷积 function,我们可以写 F=H*G。

那么我可以通过以下方式找到 H:H=F/G 还是否?

我尝试编写这样的代码:

    # -*- coding: utf-8 -*-
"""
Created on Wed Dec 15 09:46:52 2021

@author: 20210113-1
"""

import numpy as np
import scipy.signal
import matplotlib.pyplot as plt
from scipy.fft import fft, fftfreq,ifft

# Define heaviside function
H = lambda x:np.sin(8*x)+np.cos(2*x)
#define gaussian
gauss = lambda x, sig: np.exp(-( (x)/float(sig))**2 )+3

X = np.linspace(-10, 30, num=1000)
X2 = np.linspace(-10,30, num=1000)

# convolute a heaviside with a gaussian
# H_c = np.convolve( H(X),  gauss(X, 1),  mode="same"  )
input_pulse=H(X)

H_c = scipy.signal.convolve(H(X),  gauss(X2, 1), mode='full') #/ c.sum()


output_pulse=H_c 
# deconvolute a the result
H_dc, er = scipy.signal.deconvolve(H_c, gauss(X2, 1) )



SAMPLE_RATE = 20 # Hertz
DURATION = 5  # Seconds
N =len(input_pulse)

yf = fft(input_pulse)
xf = fftfreq(N, 1 / SAMPLE_RATE)

SAMPLE_RATE = 20 # Hertz
DURATION = 5  # Seconds
N =len(output_pulse)

yff = fft(output_pulse)
xff = fftfreq(N, 1 / SAMPLE_RATE)



#### Plot #### 
fig , ax = plt.subplots(nrows=6, figsize=(6,7))
ax[0].plot( H(X),          color="#907700", label="Heaviside",    lw=3 ) 
ax[1].plot( gauss(X, 1),  color="#907700", label="Gauss filter", lw=3 )
ax[2].plot( H_c/H_c.max(), color="#325cab", label="convoluted" ,  lw=3 ) 
ax[3].plot( H_dc,          color="#ab4232", label="deconvoluted", lw=3 ) 
ax[4].plot( xf, np.abs(yf),         color="#ab4232", label="FFT input", lw=3 ) 
ax[5].plot(xff, np.abs(yff),         color="#ab4232", label="FFT output", lw=3 ) 

for i in range(len(ax)):
    # ax[i].set_xlim([0, len(X)])
    # ax[i].set_ylim([-0.07, 1.2])
    ax[i].legend(loc=4)
plt.show()

impulse=ifft(fft(output_pulse)/fft(input_pulse))

但我不能以特定方式使用它,因为返回此错误:

ValueError:操作数无法与形状一起广播 (1999,) (1000,)

所以我有两个问题:

1-我可以用这种方法计算卷积 function 吗?

2-如果可以,我该如何在代码中实现?

您可以将两个信号填充到一个共同的大小,这可以通过指定要应用的 FFT 的大小来实现。

impulse=ifft(fft(output_pulse, 2048)/fft(input_pulse, 2048))[:len(X)]

然后你删除额外的填充

对于您的特定示例,它运行良好,但并非总是如此。 除非每个符号有多个样本,否则反卷积并不容易准确求解。

scipy deconvolve方法通过多项式除法计算卷积,给出商和残差,范数或残差可能远大于商的范数,如果幸运的话,残差的范数会很小,并且商给出了很好的近似值的反卷积。

如果信号是周期性的,则此 fft 反卷积起作用,您将信号与其自身无限次连接。 当我们做这个填充时,我们告诉它计算一个周期性信号,在两个连续副本之间有一个“静默”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM