我想过滤掉不需要的频率并保持60Hz的信号。
这是我到目前为止所做的:
import numpy as np
from scipy.fftpack import rfft, irfft, fftfreq
#
time = np.linspace(0,1,1000)
in_sig = np.cos(54*np.pi*time) + np.cos(60*np.pi*time) + np.sin(66*np.pi*time);
high_freq = 62;
low_freq = 58;
freqs = fftfreq(len(in_sig), d=time[1]-time[0])
filt_sig = rfft(in_sig)
cut_filt_sig = filt_sig.copy()
cut_filt_sig[(freqs<low_freq)] = 0
cut_filt_sig[(freqs>high_freq)] = 0
cut_in_sig = irfft(cut_filt_sig)
from pylab import *
figure(figsize=(10, 6))
subplot(221);plot(time,in_sig); title('Input signal');
subplot(222);plot(freqs,filt_sig);xlim(0,100);title('FFT of the input signal');
subplot(223);plot(time,cut_in_sig); title('Filtered signal');
xlabel('Time (s)')
subplot(224);plot(freqs,cut_filt_sig);xlim(0,100); title('FFT of the filtered signal');
xlabel('Freq. (Hz)')
show()
正如我所看到的,滤波后的信号在边缘处具有较低的幅度,我认为这可能是由于应用了矩形窗口所致。您建议使用哪些窗口来改善输出?
答案 0 :(得分:0)
问题可能来自numpy的linspace()
。默认模式是包括端点stop
。因此time
是0, 1/999, 2/999, ..., 1
。相反,fft
处理长度为N
的信号作为在0, T/N, ... , T(N-1)/N
采样的周期性信号,从而避免了端点的冗余。
因此,所计算的DFT使用长度为T = 1000/999的帧。因此,DFT的频率为k * 999/1000,而不是k。由于帧的长度不是信号周期(1 / 6s)的倍数,因此发生了名为spectral leakage的问题。
为避免频谱泄漏,可以通过删除端点将帧的长度缩短为周期的倍数:
time = np.linspace(0,1,1000,endpoint=False)
它返回time
为0、1 / 1000,.... 999/1000,由DFT处理为长度为1的帧,该帧是输入信号周期的倍数(1 / 6s)。
如果帧的长度不是信号周期的倍数,则输入信号可以为windowed,以部分缓解与帧边缘处的不连续性有关的影响,但会产生混淆频率仍然存在。 最后,通过将峰值的频率估计为相对于功率密度的平均频率,可以适当地计算实际频率。看到我的回答 Why are frequency values rounded in signal using FFT?