傅立叶空间滤波

时间:2010-09-23 06:28:28

标签: python numpy scipy signal-processing fft

我有一个长度为T的实矢量时间序列x和一个长度为t <&lt;&lt; T. h是傅立叶空间中的滤波器,真实且对称。大概是1 / f。

我想用h过滤x得到y。

假设t == T且长度为T的FFT可以适合存储器(两者都不是真的)。要在python中获取我的过滤后的x,我会这样做:

import numpy as np
from scipy.signal import fft, ifft

y = np.real( np.ifft( np.fft(x) * h ) ) )

由于条件不成立,我尝试了下面的黑客攻击:

  1. 选择填充尺寸P < t / 2,选择块大小B使得B + 2P是一个好的FFT大小
  2. 通过样条插值将h缩放为大小为B + 2P&gt; t(h_scaled)
  3. y = [];环:
    • 从x(称为x_b)
    • 获取长度为B + 2P的块
    • 执行y_b = ifft(fft(x_b)* h_scaled)
    • 从y_b的任一侧删除填充P并与y
    • 连接
    • 通过P
    • 选择下一个与最后重叠的x_b
  4. 这是一个好策略吗?如何以良好的方式选择填充P?这样做的正确方法是什么?我不太了解信号处理。这是一个学习的好机会。

    我正在使用cuFFT来加快速度,因此如果大部分操作都是FFT,那就太棒了。实际问题是3D。另外,我并不关心非因果过滤器中的伪影。

    谢谢, 保罗。

1 个答案:

答案 0 :(得分:6)

你走在正确的轨道上。该技术称为overlap-save processingt是否足够短,以至于该长度的FFT适合内存?如果是这样,您可以选择B块大小B > 2*min(length(x),length(h)),以便进行快速转换。然后当你处理时,你放弃y_b的前半部分,而不是从两端掉落。

要了解为什么要放弃上半部分,请记住频谱乘法与时域中的循环卷积相同。与零填充h进行对比会在结果的前半部分产生奇怪的毛刺瞬变,但到了后半部分所有瞬态都消失了,因为x中的圆形包络点与零部分对齐h。用"Theory and Application of Digital Signal Processing" by Lawrence Rabiner and Bernard Gold中的图片对此进行了很好的解释。

重要的是,您的时域过滤器至少在一端逐渐变为0,这样您就不会出现响铃现象。您提到h在频域中是真实的,这意味着它具有全0阶段。通常,这种信号仅以循环方式连续,并且当用作滤波器时将在整个频带中产生失真。创建合理滤波器的一种简单方法是在频域中使用0相位,逆变换和旋转进行设计。例如:

def OneOverF(N):
    import numpy as np
    N2 = N/2; #N has to be even!
    x = np.hstack((1, np.arange(1, N2+1), np.arange(N2-1, 0, -1)))
    hf = 1/(2*np.pi*x/N2)
    ht = np.real(np.fft.ifft(hf)) # discard tiny imag part from numerical error
    htrot = np.roll(ht, N2)
    htwin = htrot * np.hamming(N)
    return ht, htrot, htwin

(我对Python很陌生,请告诉我是否有更好的方法来编写代码)。

如果您比较hthtrothtwin的频率响应,您会看到以下内容(x轴的归一化频率最高为pi): 1/f filters with length 64

ht,在顶部,有很多波纹。这是由于边缘的不连续性。 htrot,在中间,更好,但仍然有波纹。 htwin很好而且很平滑,代价是以稍高的频率展平。请注意,您可以使用较大的N值来扩展直线段的长度。

我写过关于不连续性的问题,如果你想看到更多的细节,还在another SO question写了一个Matlab / Octave例子。