[英]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()
如我所見,濾波后的信號在邊緣處具有較低的幅度,我認為這可能是由於應用了矩形窗口所致。 您將建議使用哪些窗口來改善輸出?
問題可能來自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),因此會發生稱為頻譜泄漏的問題。
為了避免頻譜泄漏,可以通過刪除端點將幀的長度縮短為周期的倍數:
time = np.linspace(0,1,1000,endpoint=False)
它返回time
0、1 / 1000,.... 999/1000,由DFT處理為長度為1的幀,該長度是輸入信號周期(1 / 6s)的倍數。
如果幀的長度不是信號周期的倍數,則可以對輸入信號進行加窗處理 ,以部分緩解與幀邊緣處的不連續性有關的影響,但是仍然存在雜散頻率。 最后,通過將峰值的頻率估計為相對於功率密度的平均頻率,可以適當地計算實際頻率。 請參閱我的答案, 為什么頻率值會使用FFT在信號中取整?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.