短时傅里叶变换(Short Time Fourier Transform)原理及 Python 实现

原理

  短时傅里叶变换(Short Time Fourier Transform, STFT) 是一个用于语音信号处理的通用工具.它定义了一个非常有用的时间和频率分布类, 其指定了任意信号随时间和频率变化的复数幅度. 实际上,计算短时傅里叶变换的过程是把一个较长的时间信号分成相同长度的更短的段, 在每个更短的段上计算傅里叶变换, 即傅里叶频谱.

短时傅里叶变换通常的数学定义如下:

其中,

DTFT (Decrete Time Fourier Transform) 为离散时间傅里叶变换.  其数学公式, 如下所示:

  其中,  x(n) 为在采样数 n 处的信号幅度. ω~ 的定义如下:

  实现时, 短时傅里叶变换被计算为一系列加窗数据帧的快速傅里叶变换 (Fast Fourier Transform, FFT),其中窗口随时间 “滑动” (slide) 或“跳跃” (hop) 。

Python 实现

  在程序中, frame_size 为将信号分为较短的帧的大小, 在语音处理中, 通常帧大小在 20ms 到 40ms 之间. 这里设置为 25ms, 即 frame_size = 0.025;

  frame_stride 为相邻帧的滑动尺寸或跳跃尺寸, 通常帧的滑动尺寸在 10ms 到 20ms 之间, 这里设置为 10ms, 即 frame_stride = 0.01. 此时, 相邻帧的交叠大小为 15ms;

  窗函数采用汉明窗函数 (Hamming Function) ;

  在每一帧, 进行 512 点快速傅里叶变换, 即 NFFT = 512. 具体程序如下:

# -*- coding: utf8 -*-
import numpy as np

def calc_stft(signal, sample_rate=16000, frame_size=0.025, frame_stride=0.01, winfunc=np.hamming, NFFT=512):

    # Calculate the number of frames from the signal
    frame_length = frame_size * sample_rate
    frame_step = frame_stride * sample_rate
    signal_length = len(signal)
    frame_length = int(round(frame_length))
    frame_step = int(round(frame_step))
    num_frames = 1 + int(np.ceil(float(np.abs(signal_length - frame_length)) / frame_step))
    # zero padding
    pad_signal_length = num_frames * frame_step + frame_length
    z = np.zeros((pad_signal_length - signal_length))
    # Pad signal to make sure that all frames have equal number of samples
    # without truncating any samples from the original signal
    pad_signal = np.append(signal, z)

    # Slice the signal into frames from indices
    indices = np.tile(np.arange(0, frame_length), (num_frames, 1)) +             np.tile(np.arange(0, num_frames * frame_step, frame_step), (frame_length, 1)).T
    frames = pad_signal[indices.astype(np.int32, copy=False)]
    # Get windowed frames
    frames *= winfunc(frame_length)
    # Compute the one-dimensional n-point discrete Fourier Transform(DFT) of
    # a real-valued array by means of an efficient algorithm called Fast Fourier Transform (FFT)
    mag_frames = np.absolute(np.fft.rfft(frames, NFFT))
    # Compute power spectrum
    pow_frames = (1.0 / NFFT) * ((mag_frames) ** 2)

    return pow_frames

if __name__ == ‘__main__‘:
    import scipy.io.wavfile
    import matplotlib.pyplot as plt

    # Read wav file
    # "OSR_us_000_0010_8k.wav" is downloaded from http://www.voiptroubleshooter.com/open_speech/american.html
    sample_rate, signal = scipy.io.wavfile.read("OSR_us_000_0010_8k.wav")
    # Get speech data in the first 2 seconds
    signal = signal[0:int(2. * sample_rate)]

    # Calculate the short time fourier transform
    pow_spec = calc_stft(signal, sample_rate)

    plt.imshow(pow_spec)
    plt.tight_layout()
    plt.show()

参考资料

1. DISCRETE TIME FOURIER TRANSFORM (DTFT). https://www.dsprelated.com/freebooks/mdft/Discrete_Time_Fourier_Transform.html

2. THE SHORT-TIME FOURIER TRANSFORM. https://www.dsprelated.com/freebooks/sasp/Short_Time_Fourier_Transform.html

3. Short-time Fourier transform. https://en.wikipedia.org/wiki/Short-time_Fourier_transform

4. Speech Processing for Machine Learning: Filter banks, Mel-Frequency Cepstral Coefficients (MFCCs) and What‘s In-Between. https://haythamfayek.com/2016/04/21/speech-processing-for-machine-learning.html

原文地址:https://www.cnblogs.com/klchang/p/9280509.html

时间: 2024-10-06 10:55:20

短时傅里叶变换(Short Time Fourier Transform)原理及 Python 实现的相关文章

离散傅里叶变换(Discrete Fourier Transform,缩写为DFT)

核心函数: cvDFT 程序: 代码: #include "cv.h" #include "cxcore.h" #include "highgui.h" #include <iostream> int DFT(int argc,char** argv)  //离散傅里叶变换(Discrete Fourier Transform,缩写为DFT) { IplImage* src=cvLoadImage("e:\\picture\

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Discrete Fourier Transform

2.8 离散的傅立叶变换 目标 我们要寻找以下问题的答案: 1.什么是傅立叶变换,为什么我们要用这个? 2.在OpenCV中如何做到? 3.例如copyMakeBorder(),merge(),dft(),getOptimalDFGSize(),log()以及normalize()函数的用法. 源代码 你可以从这里下载或者从samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete找到代码. #include "openc

Personal reminder (or CheetSheet) about Fourier Transform

Recently, I'm studying Fourier Transform by watching the lectures from Stanford University. I felt that I already forget the math basics that I've learnt in college. So, to set up a quick lookup table for myself, I decide to write something to memori

短时傅里叶变换

短时傅里叶变换可以看做移位信号x[n+m]通过窗w[m]的傅里叶变换.当n改变时,信号x[m]滑动着通过窗w[m].对每一个n,可以看到信号的一段不同部分. 当然,也可以看做将窗平移,而保持傅里叶分析的时间原点固定不变,由此可以得出稍许不同的另一个短时傅里叶变换定义式. 当窗对于所有m均为1,即不加窗时,X[n, λ)=Σx[n+m]e-jλm=Σx[n+m]e-jλ(n+m)ejλn=X(ejλ)ejλn

free induction decay fourier transform

1 % A script for display the process of Fourier Transform of FID 2 % FID stands for Free Induction Decay,which is a signal over time domain.We 3 % can get the signal over frequency through fourier transform.And FID is 4 % one of the most important si

OpenCV Tutorials &mdash;&mdash; Discrete Fourier Transform

The Fourier Transform will decompose an image into its sinus and cosines components. In other words, it will transform an image from its spatial domain to its frequency domain. 将图像从空域转换到频域,使其由 sin 和 cos 成分构成 The idea is that any function may be appro

浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理

浅谈范德蒙德(Vandermonde)方阵的逆矩阵与拉格朗日(Lagrange)插值的关系以及快速傅里叶变换(FFT)中IDFT的原理 只要稍微看过一点线性代数的应该都知道范德蒙德行列式. \[V(x_0,x_1,\cdots ,x_{n-1})=\begin{bmatrix} {1}&{1}&{\cdots}&{1}\{x_{0}}&{x_{1}}&{\cdots}&{x_{n-1}}\{x_{0}^2}&{x_{1}^2}&{\cdots

主成分分析法原理及其python实现

主成分分析法原理及其python实现 前言: 这片文章主要参考了Andrew Ng的Machine Learning课程讲义,我进行了翻译,并配上了一个python演示demo加深理解. 本文主要介绍一种降维算法,主成分分析法,Principal Components Analysis,简称PCA,这种方法的目标是找到一个数据近似集中的子空间,至于如何找到这个子空间,下文会给出详细的介绍,PCA比其他降维算法更加直接,只需要进行一次特征向量的计算即可.(在Matlab,python,R中这个可以

机器学习-朴素贝叶斯原理及Python实现

机器学习-朴素贝叶斯原理及Python实现 贝叶斯公式 P(A|B) = (P(B|A)P(A))/P(B) 举例:苹果10个,有2个黄色:梨10个,有6个黄色,求拿出一个黄色水果,是苹果的概率. 代入公式: P(苹果|黄色) = (P(黄色|苹果)P(苹果))/P(黄色) P(黄色) = (2+6)/20 = 2/5 P(苹果) = 10/20 = 1/2 = 0.5 P(黄色|苹果)=1/5 P(黄色|苹果)P(苹果) = P(黄色,苹果) = 1/5*1/2 = 1/10 = 0.1 P(