我正在尝试使用FFT和逆FFT(IFFT)在Matlab中过滤(实际)信号。我有一个IIR滤波器(系数'b'和'a')。我期待(大约?)相同的结果,就好像我只是这样做:
filteredSignal = filter(b,a,signal);
所以这就是我所做的:
NFFT = length(signal);
FFTsignal = fft(signal, NFFT);
FilterFreqResponse = freqz(b,a,NFFT);
FFTfilteredSignal = FFTsignal .* FilterFreqResponse;
filteredSignal = ifft(FFTfilteredSignal, NFFT);
这里的问题是结果信号(filteredSignal
)很复杂。我想要一个真实的信号(作为我的输入信号)。 filter
函数也返回实际信号。那么......我做错了什么?是否无法在IIR滤波器中使用基于FFT的滤波?我的意思是:我的滤波器的频率响应相对于原点是不对称的,所以滤波后的信号的频谱也不会是对称的...所以时域中的滤波信号不能是真实的......?
PS:ifft函数中有一个“对称”选项:
filteredSignal = ifft(FFTfilteredSignal, NFFT, 'symmetric');
如果我这样做,过滤的信号现在是真实的...但是与我直接使用“过滤器”功能的那个明显不同(幅度和相位)。而这种“对称”选项显然会丢弃想象中的部分,或类似的东西,所以我猜它可能不是一个好主意....
提前多多感谢! (对不起我的英文)
答案 0 :(得分:3)
仅使用结果的实部
是不正确的你的答案很复杂的原因是没有对称地执行逐点乘法:即,对于有意义的答案,向量FilterResponse必须关于其中心元素对称。你应该只建立滤波器响应,直到Fs / 2(即一个较小的矢量),然后写一些逻辑,将它共轭对称地应用于镜像频率。或者,Matlab可以通过以下方式自动执行此操作:FilterFreqResponse = freqz(b,a,NFFT,'whole')
只有这样才能将'symmetric'选项与ifft一起使用,因为它的目的是防止你创建的对称性之间可能存在的小数值误差。
答案 1 :(得分:1)
使用逆FFT的实部:
filteredSignal = real(ifft(FFTfilteredSignal, NFFT));
答案 2 :(得分:1)
FilterFreqResponse
的评估位于NFFT
个点,仅围绕单位圆的上半部分。你试过FilterFreqResponse = freqz(b,a,NFFT,'whole')
吗?
答案 3 :(得分:0)
频域中的乘法是时域中的循环卷积。为了摆脱循环卷积伪像,你需要在FFT之前用滤波器响应的长度对信号进行零填充,镜像你的频率响应滤波器,使其在乘法之前是复共轭对称的(可能使两个向量长度为2N) case),然后在IFFT之后,抛弃添加的填充,或保留它以进行额外的重叠添加/保存处理。