2011年08月02日 星期二 00:10
import numpy, pylab
from numpy import fft, pi, sin
x = numpy.arange(0,2,0.01)
signal = sin(2*pi*(x-1/4))
noise = 0.5*numpy.random.randn(len(x))
rawsignal = signal + noise
FFT = fft.fft(rawsignal)
pylab.plot(x,signal, label = 'noise free signal')
pylab.plot(x,rawsignal, label = 'noised signal')
pylab.plot(x,FFT, label = 'FFT signal')
pylab.legend()
为什么fft.fft()得到的结果不是有用信号?
2011年08月02日 星期二 06:47
FFT得到的是频域信号,和时域信号画在一起没有意义。下面是修改之后的程序:
import numpy, pylab
from numpy import fft, pi, sin, log10, abs
x = numpy.arange(0,2,0.01)
signal = sin(2*pi*(x-1/4))
noise = 0.5*numpy.random.randn(len(x))
rawsignal = signal + noise
FFT = fft.fft(rawsignal)
pylab.subplot(211)
pylab.plot(x,signal, label = 'noise free signal')
pylab.plot(x,rawsignal, label = 'noised signal')
pylab.subplot(212)
f = numpy.linspace(0, 0.5/(x[1]-x[0]), len(x)/2+1)
p = 20*log10(abs(FFT))[:len(x)/2+1]
pylab.plot(f,p, label = 'FFT signal')
pylab.legend()
由下图可以看到频率在1Hz处频谱有一个峰值,那个就是1Hz正弦波信号对应的频谱,其它的频率的频谱都是噪声信号的。根据信号的频谱设计一个滤波器对信号进行滤波即可。也可以用FFT滤波器,删除频谱中噪声信号的成分之后再用IFFT转换会时域信号。
2011年08月02日 星期二 15:43
请问 如何用FFT滤波器,删除频谱中噪声信号的成分之后再用IFFT转换会时域信号?
能否就上面的例子演示下。
2011年08月02日 星期二 18:15
你的例子中数据的长度不是2的整数次幂,你要滤波的实际数据是怎样的?
2011年08月03日 星期三 02:37
可以将例子中的数据长度改成2的任意整数次幂,我想看看FFT虑波去除噪生效果.
2011年08月03日 星期三 08:50
from numpy import arange, sin, random, fft, pi, linspace, log10, zeros
from pylab import subplot, plot, legend, semilogx
x = arange(0,2,1.0/2048)
signal = sin(2*pi*(5*x-1/4.0))
noise = 0.5*random.randn(len(x))
rawsignal = signal + noise
FFT = fft.rfft(rawsignal)
mask = zeros(len(FFT))
mask[10] = 1
subplot(211)
plot(x,signal, label = 'noise free signal')
plot(x,rawsignal, label = 'noised signal')
plot(x, fft.irfft(FFT*mask), label='fft filter', lw=2)
subplot(212)
f = linspace(0, 0.5/(x[1]-x[0]), len(x)/2+1)
p = 20*log10(abs(FFT))
semilogx(f,p, label = 'FFT signal')
legend()
滤波的结果和mask数组有关,这里只过滤出正弦波所对应的频率,所以滤波效果很好。
2011年08月03日 星期三 14:53
如果不知道有用信号频率的情况,如何设定 mask数组 ?
2011年08月03日 星期三 18:19
你还是举个实际的例子吧。如果只是正弦波的话,只要找到FFT中的最大值,将其ifft即可。
2011年08月03日 星期三 20:22
你发的这个数据是什么意思?逗号应该是小数点吗?
你用前面的程序把数据的频谱画出来看看。
2011年08月03日 星期三 20:45
代替 前面例子中的 signal = sin(2*pi*(5*x-1/4.0))
逗号应该是小数点(电脑系统导致的问题), 你的意思就是先画出原始信号的频谱,找到有用信号的频率位置 i ,再定义 mask[i] = 1 , 即可?
2011年08月03日 星期三 20:58
是啊,你自己先试试看吧。
2011年08月03日 星期三 21:11
貌似我的原始信号fft后看不出特定频率的峰值, 此外频率轴
f = numpy.linspace(0, 0.5/(x[1]-x[0]), len(x)/2+1),中间参数为什么不是 1/(x[1]-x[0])
2011年08月03日 星期三 21:57
这样的信号只需设计一个FIR低通滤波器,然后用filtfilt()滤波即可,不需要频域滤波。
2011年08月04日 星期四 09:03
x[1]-x[0] 是取样周期T,1/(x[1]-x[0])是取样频率Fs。而当取样频率为Fs时,它所取样的信号的最高频率为Fs/2。这个被称为香农定理。
Zeuux © 2024
京ICP备05028076号