【问题标题】:Erasing noise from fft chart从 fft 图表中消除噪音
【发布时间】:2018-05-17 17:46:33
【问题描述】:

您知道如何从 FFT 中删除这么多噪声吗? 这是我的 FFT 代码:

import numpy as np

fft1 = (Bx[51:-14])
fft2 = (By[1:-14])


# Loop for FFT data
for dataset in [fft1]:
    dataset = np.asarray(dataset)
    psd = np.abs(np.fft.fft(dataset))**2
    freq = np.fft.fftfreq(dataset.size, float(300)/dataset.size)
    plt.semilogy(freq[freq>0], psd[freq>0]/dataset.size**2, color='r')


for dataset2 in [fft2]:
    dataset2 = np.asarray(dataset2)
    psd2 = np.abs(np.fft.fft(dataset2))**2
    freq2 = np.fft.fftfreq(dataset2.size, float(300)/dataset2.size)
    plt.semilogy(freq2[freq2>0], psd2[freq2>0]/dataset2.size**2, color='b')

我得到了什么:

我需要什么:

有什么想法吗? Welch 不起作用,所以如您所见,我不想平滑我的图表,而是将这么多的噪音消除到第二张图片上呈现的水平。

这就是韦尔奇所做的: 和一些代码:

freqs, psd = scipy.signal.welch(dataset, fs=300, window='hamming')

更新的韦尔奇:

一点代码:

# Loop for FFT data
for dataset in [fft1]:
    dataset = np.asarray(dataset)
    freqs, psd = welch(dataset, fs=266336/300, window='hamming', nperseg=512)
    plt.semilogy(freqs, psd/dataset.size**2, color='r')

for dataset2 in [fft2]:
    dataset2 = np.asarray(dataset2)
    freqs2, psd2 = welch(dataset2, fs=266336/300, window='hamming', nperseg=512)
    plt.semilogy(freqs2, psd2/dataset2.size**2, color='b')

如您所见,Welch 配置良好,显示 60 Hz 电力线和谐波模式。这几乎是好的,但它完全平滑了我的情节。参见图二,这是所需的。顺便提一句。 y 尺度在 Welch 图中是错误的,但这只是两者的幂数据的一个例子。

我已更改为 nperseg=8192 并且它有效。看看结果。

【问题讨论】:

  • 你不能“抹去”噪音;它就在那里,尤其是当您使用原始 FFT 进行频谱密度估计时。平滑通常是要走的路,那么是什么让您认为 Welch 不适合您?下面的情节看起来与我期望韦尔奇制作的完全一样。
  • welch 有一个参数 nperseg。较高的值可提供更好的频率分辨率,较低的值可提供更多的降噪。从signal.welch(dataset, fs=300, window='hamming', nperseg=256) 开始,然后尝试nperseg=512,如果噪音仍然可以接受。我建议您使用这些值来感受它们(也可以查看noverlap 参数)。
  • 频率轴不匹配。您的 FFT 图明显错误,或者您的采样率不是 300 Hz。 (我希望是后者,否则这可能表明您的数据有问题。)您是否按照我的建议尝试过使用nperseg?这应该可以让你获得你想要的任何数量的微小波动(噪音)。
  • 我明白了.. 好吧,fs 是采样频率。如果您在 300 秒内有 266336 个样本,则应该是 266336 / 300。如果您有那么多样本,您可以尝试非常高的 noverlap 值。也许 4096 或更多?
  • 代码和图像比 cmets 更容易 :) 请参阅我的答案,该答案显示了 nperseg 参数的效果。 (我不小心在上面的评论中写了noverlap。)应该可以达到你想要的效果(8192用我的示例数据),不是吗?

标签: python python-2.7 numpy fft noise


【解决方案1】:

以下示例展示了如何使用nperseg 来控制频率分辨率与降噪之间的权衡:

nperseg 设置为信号的长度或多或少等同于使用没有任何平均的FFT。

这是生成此图像的代码:

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

plt.figure(figsize=[8, 12])

n = 2**21
fs = 887

# example data
x = np.random.randn(n)
x += np.sin(np.cumsum(0.42 + np.random.randn(n) * 0.01)) * 5
x = signal.lfilter([1, 0.5], 2, x)

plt.subplot(3, 2, 1)
plt.semilogy(np.abs(np.fft.fft(x)[:n//2])**2 / n**2, label='FFT')
plt.legend(loc='best')

for i, nperseg in enumerate([128, 512, 8192, 65536, n]):
    plt.subplot(3, 2, i+2)
    f, psd = signal.welch(x, fs=fs, window='hamming', nperseg=nperseg, noverlap=0)
    plt.semilogy(f, psd, label='nperseg={}'.format(nperseg))
    plt.legend(loc='best')

plt.show()

【讨论】:

  • 非常感谢您帮我解决这个问题 :) 干杯人。我猜话题已经结束了。
猜你喜欢
  • 2016-06-13
  • 1970-01-01
  • 2012-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 2017-02-27
  • 2021-12-21
相关资源
最近更新 更多