前言
利用FFT进行频率的估计时精度较低,若信号采样率为,FFT点数为,则信号精度仅为,需要对FFT后的频率数据进行插值来获取更高的精度。本文推导三点插值公式。
一、插值思路
可用FFT后的信号模值或者模值的对数进行插值。以信号模值为例,设模值最大点为,对应的频点为,左右两边点的模值分别为和,对应的频点分别为和。则三点插值的思路是将(对数)模值波形近似为抛物线,利用抛物线公式找出最大值。
设抛物线公式为
插值思路就是利用三点求出抛物线系数a、b和c的值,并计算得到极值点对应的频点
二、插值公式推导
将三点代入公式可得:
(1)
(2)
(3)
且满足,即、和是一个等差数列。
由公式(3)-公式(1)可得:
整理可得:
(4)
再由公式(1)+公式(3)-2公式(2)可得:
(5)
根据、和等差数列的关系可得:
代入公式(5)可解出a为
(6)
由公式(4)和公式(6)可得极值点对应的频偏为
上式中,第一项是FFT后最大值点对应的频点,第二项是通过插值需要补偿的频偏。
三、仿真验证
以1024点正弦波为例,进行1024点的FFT,插值核心代码如下:
function fe = FFT_Interpolate(FFT_in, nfft)
% FFT_in -- 复数正弦波
% nfft -- FFT点数
Freq_Domain = fft(FFT_in, nfft);
abs_F = abs(Freq_Domain);
[max_value, index] = max(abs_F);
if(index == 1)
left_value = abs_F(nfft);
right_value = abs_F(2);
elseif(index == nfft)
left_value = abs_F(nfft - 1);
right_value = abs_F(1);
else
left_value = abs_F(index - 1);
right_value = abs_F(index + 1);
end
delta_f = (left_value - right_value) / (right_value + left_value - 2 * max_value) / 2;
fe = (index - 1 + delta_f) * fs / nfft;
if(fe > fs / 2)
fe = fe - fs;
end