用频率噪声阻止信号的FFT

时间:2016-01-07 07:49:23

标签: python fft

我的信号相位大约为40 Hz,噪音很小。我试图分析它以1秒钟的方式找到频率,我正在使用python来模拟这个。我发现阻塞的FFT分析不准确,所以我查看了具体的块,看看为什么会发生这种情况,并发现在以后的时间里,FFT没有意义,并且在40 Hz附近有一个尖峰。我正在使用Python进行此模拟,这里是代码:

首先创建信号:

# Time
time = 500
# sample spacing
T = 1.0 / 5000.0
sample_freq = 1.0/T
#number of points
N = time / T
x = np.linspace(0.0, N*T, N)
noise = np.random.normal(scale = 0.01, size = len(x))
noisy_freq = 40 + noise
y = 50.0 * np.sin(noisy_freq * 2.0*np.pi*x) + 1.0*np.sin(80.0 * 2.0*np.pi*x)

然后我在第一秒看了FFT并收到:

first second

并放大到40 Hz左右

zoom of first second

然后我看了第10块:

10th second

并缩放到40 Hz左右:

10th second zoom

可见信号已经降级,这条水平线开始发展,我不知道是什么来的。

然后我看了第100秒,这就是我发现的:

100th second

并缩放到40 Hz左右:

100th second zoom

并且FFT响应几乎不能确定40 Hz附近的尖峰。我无法弄清楚为什么信号会在以后降低。我尝试过使用窗口函数,但这没有用。

以下是我用来创建FFT的代码:

sample_freq = 1/T
time_step = 10
step = int(time_step * sample_freq)

x = x[100/T:101/T]
y = y[100/T:101/T]

flat = flat_top_windowing(len(y))
y = y*flat

yf = np.abs(np.fft.fft(y))
x_n = x.size

xf = np.fft.fftfreq(x_n,1/sample_freq)

plt.close()
plt.plot(xf, 2.0/N * yf[0:N/2])
plt.grid()
plt.show()

1 个答案:

答案 0 :(得分:2)

问题在于生成的信号:

np.sin(noisy_freq * 2.0*np.pi*x)

随着时间的推移(变量x中的值),乘法noisy_freq*x意味着noisy_freq变体对sin阶段的影响不断增加。鉴于相位变化越来越大,实际的瞬时频率变化的程度要大得多(最终看起来它会在整个频谱上随机跳跃)。

要生成频率调制信号,您应该将频率贡献与:

进行整合
dphi = 2.0*np.pi*noisy_freq[:-1]*T; # per sample frequency contributions
dphi = np.insert(dphi, 0, 0);       # set the initial phase to 0
phi  = np.cumsum(dphi);             # integrate phase

y = 50.0 * np.sin(phi) + 1.0*np.sin(80.0 * 2.0*np.pi*x)