是否有必要应用一些窗口方法来获得 FFT?爪哇

信息处理 fft 窗函数 爪哇
2022-02-02 21:31:17

我读到需要窗口来应用滤波器(低通、高通、带通或带阻),但不适用于 FFT。

1. 什么优点适用窗口或缺点不适用?

2. 选择尺码的标准是什么(我的长度W:汉窗的长度)?

3. 我在哪里可以找到具体的文献?

我的代码:

假设一个样本数组存储在

integer SIZE = 16384; //SomeValue
short[] sSamples = new short[SIZE];
sSamples = obtainSamples();  //Some method to fill my array

现在我需要获得我的 FFT。我为我的 FFT 任意选择了 4096,然后是 8 倍(或 8 fft)

FFTLength = 4096;
SIZE = 16384;
double Overlap = 0.5;
SIZE/(FFTLength*Overlap) = 8;

直接法:

complex cSamples = new complex[SIZE];
cSamples = short2Complex(sSamples);

现在我需要获取长度为 8 个样本数组的部分数组:SIZE/4

//getPartArray(from, until) maybe like System.ArrayCopy
complex[] cSamples00 = getPartArray(0,4095);
complex[] cSamples01 = getPartArray(4096,8191);
//similarly for all, from 00 until 07
complex[] cSamples01 = getPartArray(12287,16383);

最后,获得 FFT

//fft(complex[], length)
complex[] cFFT00 = fft(cSamples00,4096);
//similarly for all, from 00 until 07
complex[] cFFT07 = fft(cSamples00,4096);

窗口方法:

//int LengthW = ??  // (besides positive and odd)
double[] Wn = new double[LengthW];
//Suppose Han Window,can be Hamming, Kaiser, Blackman, etc
Wn = obtainHanWindow(LengthW);
double[] sWindowedSamples = applyingWindow(Wn,sSamples);

complex cSamples = new complex[SIZE];
cSamples = short2Complex(sWindowedSamples);

现在我需要获取长度为 8 个样本数组的部分数组:SIZE/4

//getPartArray(from, until) maybe like System.ArrayCopy
complex[] cSamples00 = getPartArray(0,4095);
complex[] cSamples01 = getPartArray(4096,8191);
//similarly for all, from 00 until 07
complex[] cSamples01 = getPartArray(12287,16383);

最后,获得 FFT

//fft(complex[], length)
complex[] cFFT00 = fft(cSamples00,4096);
//similarly for all, from 00 until 07
complex[] cFFT07 = fft(cSamples00,4096);

唯一的区别是计算一个窗口并将其应用于输入。

定义的类和方法

复杂类的定义如下:

class complex {
  public double real = 0.0;
  public double imag = 0.0;
} 

短2复杂:

short2Complex(short[] intSSample) {
  complex intCSample = new complex[intSSample.length];
  for (int i = 0; i < intSSample.length; i++) {
    complex tcomplex = new complex();
    tcomplex.real = intSSample[i];
    intCSample[i] = tcomplex;
  }
  return intCSample;
}

获取HanWindow:

double[] obtainHanWindow(int Size) {
  //Size must be Odd and Positive integer
  double[] dHan = new double[Size];
  int HalfSize = (int)Math.floor((double)Size/2);
  for (int i = 0; i < HalfSize; i++) {
    int j = 2*HalfSize - i;
    double Pi2DivSize = 2.0*Math.PI/Size;
    dHan[i] = 0.5+0.5*Math.cos(Pi2DivSize*(double)(i - HalfSize));
    dHan[j] = 0.5+0.5*Math.cos(Pi2DivSize*(double)(HalfSize - i));
  }
  dHan[HalfSize] = 1.0;
  return dHan;
}

应用窗口

applyingWindow(double[] dWn, double[] dSamples) {
  double dOutput = new double[dSamples.length]
  for (int i=0; i < dWn.length; i++) {
    dOutput[i] = 0;
    for (int j=0; j < dSamples.length; j++) {
      if(i-j>=0) {
        dOutput[i] += dSamples[j]*dWn[i-j];
      }
    }
  }
  return dOutput;
}
2个回答

图1

图 2

如你看到的; 当任意频率的正弦信号输入到“N”点 DFT 时,信号的频谱响应将不是 Delta 函数(脉冲),因为当我们考虑到丢失的终点与起点相同时在序列的周期性扩展的下一个周期中,信号的周期性扩展不再是正弦曲线。解决此问题的一种方法是确保相干采样,如图 1 所示

但只有当 DFT 引擎接收到纯单调信号时,才能进行相干采样。所以在现实世界的应用中,相干采样是不可行的。

所以,只需通过将整个信号乘以某个函数来减小不连续性的大小。

因此,当您乘以窗函数时,它消除了跳跃不连续性并消除了在未完成相干采样时引入的错误频率(参见图 3.

图 3

窗口的长度应该是信号的长度。窗口的选择可能取决于您可以容忍多少旁瓣高度。

窗户的性能

图片来源:http ://electronicdesign.com/analog/choose-right-fft-window-function-when-evaluating-precision-adcs

在执行 FFT 之前加窗是必不可少的,以确保没有频谱泄漏。由于 FT 可以很好地处理周期性数据,因此数据不连续性会影响频谱伪影。

http://www.ni.com/white-paper/4844/en/