需要解释specgram函数如何在python中工作(matplotlib - MATLAB兼容函数)

时间:2017-04-28 17:27:46

标签: python matplotlib signal-processing fft spectrogram

我正在努力将我的代码从python转换为objective c。 在matplotlib.mlab.specgram函数内部,我在fft之前看到了3个重要的函数:

 result = stride_windows(x, NFFT, noverlap, axis=0)
 result = detrend(result, detrend_func, axis=0)
 result, windowVals = apply_window(result, window, axis=0,
                                      return_window=True)
 result = np.fft.fft(result, n=pad_to, axis=0)[:numFreqs, :]

我尝试调试以了解每个目的。例如,我有输入数组:

x = [1,2,3,4,5,6,7,8,9,10,11,12]

在第一个函数stride_windows(这个以防止泄漏?)之后,如果NFFT = 4,则noverlap = 2然后:

x = [ [1,3,5,7,9],
      [2,4,6,8,10],
      [3,5,7,9,11],
      [4,6,8,10,12] 
    ]

在趋势后没有任何变化(我理解fft之前的趋势)

在apply_window里面(我不明白这一步):

    xshape = list(x.shape) 
    xshapetarg = xshape.pop(axis) // =4
    windowVals = window(np.ones(xshapetarg, dtype=x.dtype))
    //result of 4 elements [0.0, 0.75, 0.75, 0.0]
    xshapeother = xshape.pop() // =5
    otheraxis = (axis+1) % 2  // =1
    windowValsRep = stride_repeat(windowVals, xshapeother, axis=otheraxis)
    // result windowValsRep = [
                                [ 0. ,0. ,0. ,0. ,0. ,],
                                [0.75, 0.75, 0.75, 0.75, 
                                [0.75, 0.75, 0.75, 0.75, 
                                [ 0. ,0. ,0. ,0. ,0. ,]
                              ]

然后将其与x

相乘
windowValsRep * x

现在

 x =    [ 
          [ 0.  , 0.   , 0.   , 0.   , 0.   ],
          [ 1.5 , 3    , 4.5  , 6.   , 7.5  ],
          [ 2.25, 3.75 , 5.25 , 6.75 , 8.25 ],
          [ 0.  , 0.   , 0.   , 0.   , 0.   ] 
        ]

然后最后是fft,因为我知道fft只需要一个数组但在这里处理2维数组。为什么?

result = np.fft.fft(x, n=pad_to, axis=0)[:numFreqs, :]

有人可以一步一步地向我解释为什么数据需要在fft之前像这样处理吗?

谢谢,

1 个答案:

答案 0 :(得分:4)

频谱图和FFT不是一回事。 spectogram的目的是采用小的,相等大小的时间块的FFT。这产生2D傅里叶变换,其中X轴是时间块的开始时间,Y轴是该时间块中每个频率的能量(或功率等)。这使您可以查看频率成分如何随时间变化。

specgram函数的文档中对此进行了解释:

  

将数据分成NFFT长度段,并计算每个部分的频谱。窗口函数窗口应用于每个段,并且使用noverlap指定每个段的重叠量。

至于各个功能,你要问的很多东西都在触及功能的文档中有描述,但我会尝试更详细地解释一下。

documentation中所述,stride_windows的目的是将一维数据转换为连续时间块的二维数组。这些是在最终频谱图中计算FFT的时间块。在您的情况下,它们是长度为4(NFFT=4)的时间块(注意每列4个元素)。因为您设置了noverlap=2,所以每列的最后2个元素与下一列的前2个元素相同(这就是重叠的含义)。它被称为" stride"因为它使用了关于numpy数组的内部存储的技巧,允许它创建一个具有重叠窗口的数组而不需要任何额外的内存。

正如其名称所暗示的,并且如其documentation中所描述的那样,去趋势函数从信号中移除趋势。默认情况下,它使用均值,如detrend_mean documentation所述,删除信号的meanDC offset)。

apply_window函数正如其名称所暗示的那样,以及documentation所说的内容:它为每个时间块应用window function。这是必要的,因为在时间块开始和结束时突然切断信号会导致称为transients的大量突发宽带能量,这将扰乱频谱图。窗口化信号可以减少这些瞬变。默认情况下,频谱图功能使用hanning window。这会减弱每个时间块的开始和结束。

FFT实际上并不是2D。 numpy FFT function允许您指定要进行FFT的轴。所以在这种情况下,我们有一个2D数组,我们采用该数组每列的FFT。只需一步即可完成此操作,而不是手动循环每列,这样做更清洁,速度更快。