汉宁窗口傅里叶滤波后的信号恢复

4
我有一个复杂的信号,可以在傅里叶空间中看到,并希望过滤掉一些不需要的频率。我在网上读到,应该在进行傅里叶变换之前应用汉宁窗来避免泄漏。
因此,如下所示的代码,我正在对我的数据应用汉宁窗,然后对其进行傅里叶变换。作为测试,我想看看如果我不过滤任何内容,是否可以获取我的原始信号。然而,信号在边缘处变为零。
现在,我明白这是因为汉宁窗滤波器在其结束时也变为零。那么,我如何应用汉宁窗,进入频域并回到我的时间域,以恢复我的信号?如果我的信号在两端变为零,当我尝试过滤所需频率时,在时间域中得到的结果仍将在边缘处变为零。
我的方法有什么错误吗?谢谢您提供任何帮助!
这是我正在做的示例代码:
import sys
import matplotlib
def fourier(time,array):

    fft = np.fft.fft(array*np.hanning(len(array)))

    Npts = len(array)
    spacing_array = time[::-1][:-1][::-1] - time[:-1]

    if np.mean(spacing_array) - spacing_array[0] > 1.e-16:
            print "time axis not equally separated. cannot compute fft"
            sys.exit()
    spacing = spacing_array[0]

    freq = np.fft.fftfreq(Npts, spacing)

    return freq,fft

if __name__ == "__main__":
    import numpy as np
    import matplotlib.pyplot as plt

    # generate a sample signal
    sample_rate = 100.0
    nsamples = int(2.e3)
    t = np.arange(nsamples) / sample_rate
    x = np.cos(2*np.pi*0.5*t) + 0.2*np.sin(2*np.pi*2.5*t+0.1) + \
            0.2*np.sin(2*np.pi*15.3*t) + 0.1*np.sin(2*np.pi*16.7*t + 0.1) + \
                0.1*np.sin(2*np.pi*23.45*t+.8)
    y = np.cos(7*np.pi*1.1*t) + 3*np.sin(0.2*np.pi*2.8*t+1) + \
            0.2*np.sin(8*np.pi*2.7*t) + 1*np.sin(2*np.pi*t + 2.1) + \
                0.1*np.sin(0.2*np.pi*0.45*t+1.4)
    z = x*np.exp(y*1j)

    z_freq,z_fft = fourier(t,z)

    plt.clf()
    plt.figure(figsize=(8,12))

    plt.subplot(4,1,1) # original signal
    plt.plot(t,np.absolute(z))

    plt.subplot(4,1,2) # fourier transform
    plt.semilogy(sorted(z_freq),[b for (a,b) in sorted(zip(z_freq,np.absolute(z_fft)/nsamples))])

    # filtering
    plt.subplot(4,1,3)
    idx = np.where(np.abs(z_freq)>2.0)
    z_fft[idx]=0
    z_filter = np.fft.ifft(z_fft)
    plt.plot(t,np.real(z_filter))

    z_freq,z_fft = fourier(t,z_filter)
    plt.subplot(4,1,4)
    plt.semilogy(sorted(z_freq),[b for (a,b) in sorted(zip(z_freq,np.absolute(z_fft)/nsamples))])
    plt.show()

以下是翻译的结果:

其生成的图像如下所示:汉宁窗口进行滤波前后的信号时域和频域


通常情况下,频域滤波是使用重叠块和重叠-添加重叠-保存技术进行线性卷积实现的。 - Paul R
1个回答

2

回答一些你的问题。

在这种情况下,我该如何应用汉宁窗口,在频域中进行操作并恢复信号?

在你的numpy fft实现的数值精度范围内,应用傅里叶变换和逆傅里叶变换应该会返回原始信号。然而,如果在fft之前将信号乘以一个汉宁窗口,则fft和ifft的结果将是信号乘以汉宁窗口。因此,你提供的第三个图表是有意义的。它是原始信号,乘以汉宁窗口(并通过消除高于2.0的频率而平滑)。

我在网上读到,我应该在进行傅里叶变换之前应用汉宁窗口以避免泄漏。

汉宁窗口用于可能最小化频谱泄漏。在理想情况下,您可以使用有限的数据剪辑作为瓷砖,重建整个空间中的整个函数。当您的有限数据剪辑无法完全满足该目的时,您将遭受一定量的频谱泄漏。

汉宁窗口减弱了信号的起始和结束,以帮助满足“重复瓷砖”约束。话虽如此,我认为在你提供的数据上频谱泄漏不是问题,但也许在你正在分析的另一个数据集中存在问题。

有关频谱泄漏的更多信息,请转到为什么傅里叶变换中会出现频谱泄漏

如果我的信号在两端都趋近于零,当我尝试过滤所需的频率时,时间域中的结果仍将趋近于零。

这不一定是这种情况。可能是在频域中消除的频率实际上是将函数带到时间域中的模式。

第四个图表

你的第四个图表很有趣。在其中,你绘制了高频消除时间序列的傅里叶变换的结果。该函数在+/- 2处迅速衰减,因为你已经消除了这些频率。fft没有完全达到0的事实是由于离散傅里叶变换并不精确。

快速编码评论

你的代码中有一行有趣的数组切片用法。我花了一点时间,但我想评论一下你所做的。

time[::-1][:-1][::-1] # Reverse array, disregard "new" last element, ...
                      # ... then reverse again
time[1:]  # Don't consider the first element.
time[1:] == time[::-1][:-1][::-1] # These are exactly the same.
# Result: True

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接