频段通过python?

Frequency band pass in python?

我想过滤掉不需要的频率并只保留 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()

Plotted results

正如我所见,过滤后的信号在边缘处具有较低的振幅,我认为这可能是由于应用了矩形 window。您会推荐使用什么 windows 来提高输出?

问题可能来自 numpy 的 linspace()。默认模式是包含端点 stop。所以 time0, 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)

它returns time为0, 1/1000, ....999/1000,被DFT处理为长度为1的帧,即周期的倍数输入信号(1/6s)。

如果帧的长度不是信号周期的倍数,输入信号可以是windowed,以部分减轻与帧边缘不连续性相关的影响,但杂散频率仍然存在。 最后,可以通过将峰值频率估计为其相对于功率密度的平均频率来正确计算实际频率。看我的回答