为什么通过将FFT bin归零进行过滤是个坏主意?


72

通过对信号执行FFT,将部分信号归零,然后执行IFFT来过滤信号非常容易。例如:

t = linspace(0, 1, 256, endpoint=False)
x = sin(2 * pi * 3 * t) + cos(2 * pi * 100 * t)
X = fft(x)
X[64:192] = 0
y = ifft(X)

该“砖墙” FFT滤波器完全消除了高频成分。

但是我听说这不是一个好方法。

  • 为什么通常是个坏主意?
  • 在某些情况下,这是个好选择吗?

[ 如画册所建议 ]

Answers:


74

sin(ωt)/ωt

对于在FFT孔径宽度中“在区间之间”或非整数周期的任何频谱内容,这些纹波将最大。因此,如果您的原始FFT输入数据是该窗口中某些非周期性数据的窗口(例如,大多数非同步采样的“真实世界”信号),则这些特定的伪影将由零位仓位产生。

另一种看待它的方式是,每个FFT结果仓在时域中代表一定频率的正弦波。因此,将仓归零将产生与减去该正弦波相同的结果,或者等效地,添加一个具有精确FFT仓中心频率但相位相反的正弦波。请注意,如果时域中某些内容的频率在FFT宽度上不是纯粹的整数周期,那么尝试通过添加正整数周期正弦波的逆来消除它,不会产生静默,而是看起来更像“拍子”音符(不同频率的AM调制正弦波)。同样,可能不是想要的。

相反,如果您的原始时域信号只是几个纯粹的未调制正弦波,这些正弦波在FFT孔径宽度中正好是整数周期,则对FFT零位进行零位处理将删除指定的不带伪影的正弦。


3
这个答案很有用,但我更希望把重点放在吉布斯效应上。
吉姆·克莱

4
得到答案吉布斯效应的尝试已经在这里问:dsp.stackexchange.com/questions/1144/...
hotpaw2

@ hotpaw2这是一个很好的解释。但是,我需要对此进行参考,并且在确定一个方面遇到了一些困难。这是我们进行时域滤波而不是在频域工作的原因。(此外,时域可以是实时的。)但是,似乎没有人从陈述这一点开始!

这与用于过滤器设计的窗口方法有何关系?
菲利普·平托

将Von Hann窗口(等)的变换与任何矩形窗口的变换进行比较。通常,滤波器的响应要好得多,尤其是在阻带中的FFT区间之间。通常,将零位突然置零比在过渡附近未置零更糟糕。
hotpaw2

3

这个问题也让我很困惑。@ hotpaw2的解释很好。您可能对使用matlab的简单实验感兴趣。

https://poweidsplearningpath.blogspot.com/2019/04/dftidft.html


更新信息。

为了验证这一事实是否简单,我们只需要谨慎地观察一个理想(?)带通滤波器的脉冲响应的频谱,该滤波器仅将FFT分频器归零。为什么需要“谨慎”添加副词?如果我们仅使用相同大小的FFT来观察脉冲响应,就会被欺骗,如图1所示。尽管如此,如果我们在观察滤波器的输出时增加DFT的阶数,即对脉冲响应进行零填充,我们会发现所谓的吉布斯现象,即频域的波纹,如图2所示。

结果实际上来自窗口效应。如果您想完全理解问题,请参阅DSP(1)圣经的7.6章和10.1-10.2章。总结起来,这里要注意三个关键点。

  1. 窗口大小和DFT(FFT)的阶数是完全独立的。不要将它们混合在一起。
  2. 窗口的属性(类型/大小)决定了DTFT的形状。(例如,更宽的主瓣导致频率响应中更宽的瞬态频带。)
  3. DFT只是DTFT在频域中的采样。此外,DFT的阶数越高,DFT的频谱越密集。

因此,借助图2中更密集的频谱,我们可以看到理想(伪)带通滤波器的掩模。

在此处输入图片说明欺骗频率。响应。

在此处输入图片说明Freq中的Gibbs现象。响应。

(1)艾伦·V·奥本海姆和罗纳德·W·谢弗。2009。离散时间信号处理(第3版)。Prentice Hall出版社,美国新泽西上萨德尔河。

fps = 15;

LPF = 1;
HPF = 2;

n = -511:512;
n0 = 0;
imp = (n==n0);

NyquistF = 1/2*fps;

%% Ideal BPF
tmp_N = 512;
tmp_n = 0:1:tmp_N-1;
freq = ( n .* fps) ./ tmp_N;
F = fft(imp, tmp_N);  
F_bpf = IdealBandpassFilter(F, fps, LPF, HPF);
imp_rep =[real(ifft(F_bpf))'];

% Zero padding.
imp_rep2 =[zeros(1,2048) real(ifft(F_bpf))' zeros(1,2048)];

N = 2^nextpow2(length(imp_rep));
F = fft(imp_rep,N);
freq_step = fps/N;
freq = -fps/2:freq_step:fps/2-freq_step;
freq = freq(N/2+1:end)';

figure;
plot(freq,abs(F(1:N/2)));
xlabel('freq(Hz)');
ylabel('mag');
title('Mis leading Freq Response');


N = 2^nextpow2(length(imp_rep2));
F = fft(imp_rep2,N);
freq_step = fps/N;
freq = -fps/2:freq_step:fps/2-freq_step;
freq = freq(N/2+1:end)';

figure;
plot(freq,abs(F(1:N/2)));
xlabel('freq(Hz)');
ylabel('mag');
title('Zero Padding (DFT) with more points');

%% Function
function filered_signal = IdealBandpassFilter(input_signal, fs, w1, w2)

    N = length(input_signal);
    n = 0:1:N-1;
    freq = ( n .* fs) ./ N;

    filered_signal = zeros(N, 1);

    for i = 1:N
        if freq(i) > w1 & freq(i) < w2
            filered_signal(i) = input_signal(i);
        end

    end
end

可以将其转换为评论吗?
endolith

对不起,我没有足够的声誉。URL中的说明也是我自己写的。我只想提供一个测试代码,它可以可视化纹波的不良影响。
黄宝玮

1

FFT的时间分辨率差,也就是说,它没有在特定时间存在特定时间的信息。它给出了有关给定信号持续时间的现有频率分量的信息。

通过将FFT中的仓位清零,在时域中进行IFFT后分辨率较差。


然而,对于很长的信号先进行fft然后进行ifft,存在计算困难。为了避免抖动/振铃,信号的滤波必须从通带平稳过渡到阻带。
Itta Gouthami

“ FFT给出的时间分辨率很差” FFT没有给出时间分辨率,它是频谱域变换,因此,正如后面所说,它仅给出有关信号频率分量的信息。
EdParadox

FFT提供的分辨率是其窗口的长度。FFT窗口之外的任何内容都无法解析为FFT窗口内的任何内容。
hotpaw2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.