SciPy - FFTpack

傅里叶变换是在时域信号上计算的,以检查其在频域中的行为。傅里叶变换在信号和噪声处理、图像处理、音频信号处理等学科中得到应用。SciPy 提供 fftpack 模块,让用户计算快速傅里叶变换。

以下是正弦函数的示例,它将用于使用 fftpack 模块计算傅里叶变换。

快速傅里叶变换

让我们详细了解快速傅里叶变换是什么。

一维离散傅里叶变换

长度为 N 的序列 x[n] 的长度为 N 的 FFT y[k] 由 fft() 计算,逆变换由 ifft() 计算。让我们考虑以下示例

#从 fftpackage 导入 fft 和逆 fft 函数
from scipy.fftpack import fft

#创建一个包含随机 n 个数字的数组
x = np.array([1.0, 2.0, 1.0, -1.0, 1.5])

#应用 fft 函数
y = fft(x)
print y

上述程序将生成以下输出。

[ 4.50000000+0.j 2.08155948-1.65109876j -1.83155948+1.60822041j
-1.83155948-1.60822041j 2.08155948+1.65109876j ]

让我们看另一个例子

#FFT 已经在工作区中,使用相同的工作区进行逆变换

yinv = ifft(y)

print yinv

上述程序将生成以下输出。

[ 1.0+0.j   2.0+0.j   1.0+0.j   -1.0+0.j   1.5+0.j ]

scipy.fftpack 模块允许计算快速傅里叶变换。举例来说,(嘈杂的)输入信号可能如下所示 −

import numpy as np
time_step = 0.02
period = 5.
time_vec = np.arange(0, 20, time_step)
sig = np.sin(2 * np.pi / period * time_vec) + 0.5 *np.random.randn(time_vec.size)
print sig.size

我们正在创建一个时间步长为 0.02 秒的信号。最后一条语句打印信号 sig 的大小。输出结果如下 −

1000

我们不知道信号频率;我们只知道信号 sig 的采样时间步长。信号应该来自实函数,因此傅里叶变换将是对称的。 scipy.fftpack.fftfreq() 函数将生成采样频率,scipy.fftpack.fft() 将计算快速傅里叶变换。

让我们借助一个例子来理解这一点。

from scipy import fftpack
sample_freq = fftpack.fftfreq(sig.size, d = time_step)
sig_fft = fftpack.fft(sig)
print sig_fft

上述程序将生成以下输出。

array([ 
   25.45122234 +0.00000000e+00j,   6.29800973 +2.20269471e+00j,
   11.52137858 -2.00515732e+01j,   1.08111300 +1.35488579e+01j,
   …….])

离散余弦变换

离散余弦变换 (DCT) 用以不同频率振荡的余弦函数之和来表示有限数据点序列。SciPy 提供具有函数 dct 的 DCT 和具有函数 idct 的相应 IDCT。让我们考虑以下示例。

from scipy.fftpack import dct
print dct(np.array([4., 3., 5., 10., 5., 3.]))

上述程序将生成以下输出。

array([ 60., -3.48476592, -13.85640646, 11.3137085, 6., -6.31319305])

逆离散余弦变换从其离散余弦变换 (DCT) 系数重建一个序列。idct 函数是 dct 函数的逆。让我们通过以下示例来理解这一点。

from scipy.fftpack import dct
print idct(np.array([4., 3., 5., 10., 5., 3.]))

上述程序将生成以下输出。

array([ 39.15085889, -20.14213562, -6.45392043, 7.13341236,
8.14213562, -3.83035081])