【发布时间】:2017-04-01 18:44:18
【问题描述】:
我有一个复杂的信号,我可以在傅立叶空间中看到它,并且想要过滤一些我不想要的频率。我在网上看到我应该在进行傅里叶变换之前应用汉宁窗以避免泄漏。
因此,如下面的代码所示,我正在做的是将汉宁窗应用于我的数据,然后对其进行傅立叶变换。作为测试,我想看看我是否不过滤任何东西,是否可以恢复原始信号。但是,信号在边缘已变为零。
现在,我知道这是因为 Hanning 窗口过滤器在其末端也归零。在这种情况下,我如何应用汉宁窗,进入频域并在信号恢复的情况下回到我的时域?如果我的信号在末端变为零,当我尝试过滤我想要的频率时,时域中的结果仍然会在边缘变为零。
我的方法遗漏了什么/做错了什么?感谢您提供的任何帮助!
这是我正在做的示例代码:
import sys
import matplotlib
def fourier(time,array):
fft = np.fft.fft(array*np.hanning(len(array)))
Npts = len(array)
spacing_array = time[::-1][:-1][::-1] - time[:-1]
if np.mean(spacing_array) - spacing_array[0] > 1.e-16:
print "time axis not equally separated. cannot compute fft"
sys.exit()
spacing = spacing_array[0]
freq = np.fft.fftfreq(Npts, spacing)
return freq,fft
if __name__ == "__main__":
import numpy as np
import matplotlib.pyplot as plt
# generate a sample signal
sample_rate = 100.0
nsamples = int(2.e3)
t = np.arange(nsamples) / sample_rate
x = np.cos(2*np.pi*0.5*t) + 0.2*np.sin(2*np.pi*2.5*t+0.1) + \
0.2*np.sin(2*np.pi*15.3*t) + 0.1*np.sin(2*np.pi*16.7*t + 0.1) + \
0.1*np.sin(2*np.pi*23.45*t+.8)
y = np.cos(7*np.pi*1.1*t) + 3*np.sin(0.2*np.pi*2.8*t+1) + \
0.2*np.sin(8*np.pi*2.7*t) + 1*np.sin(2*np.pi*t + 2.1) + \
0.1*np.sin(0.2*np.pi*0.45*t+1.4)
z = x*np.exp(y*1j)
z_freq,z_fft = fourier(t,z)
plt.clf()
plt.figure(figsize=(8,12))
plt.subplot(4,1,1) # original signal
plt.plot(t,np.absolute(z))
plt.subplot(4,1,2) # fourier transform
plt.semilogy(sorted(z_freq),[b for (a,b) in sorted(zip(z_freq,np.absolute(z_fft)/nsamples))])
# filtering
plt.subplot(4,1,3)
idx = np.where(np.abs(z_freq)>2.0)
z_fft[idx]=0
z_filter = np.fft.ifft(z_fft)
plt.plot(t,np.real(z_filter))
z_freq,z_fft = fourier(t,z_filter)
plt.subplot(4,1,4)
plt.semilogy(sorted(z_freq),[b for (a,b) in sorted(zip(z_freq,np.absolute(z_fft)/nsamples))])
plt.show()
由此产生的图像如下: Real space and Frequency space of signal before and after filtering with Hanning window
【问题讨论】:
-
通常使用重叠块和overlap-add 或overlap-save 线性卷积技术实现频域滤波。
标签: matlab filtering signal-processing fft physics