将时域信号变换至频域加以分析的方法称为频谱分析.频谱分析的目的是把复杂的时间历程波形,经过傅里叶变换分解为若干单一的谐波分量来研究,以获得信号的频率结构以及各谐波和相位信息.
对信号进行频谱分析可以获得更多有用信息,如求得动态信号中的各个频率成分和频率分布范围,求出各个频率成分的幅值分布和能量分布,从而得到主要幅度和能量分布的频率值.
由时间函数求频谱函数的傅里叶变换公式就是将该时间函数乘以以频率为系数的指数函数之后,在负无限大到正无限大的整个区间内,对时间进行积分.这样就得到了与这个时间函数对应的.以频率为自变量的频谱函数.频谱函数是信号的频域表示方式.根据上述傅里叶变换公式,可以求出常数的频谱函数为频域中位于零频率处的一个冲激函数,表示直流信号就是一个频率等于零的信号.与此相反冲激函数的频谱函数等于常数,表示冲激函数含有无限多个、频率无限密集的正弦成分.同样的单个正弦波的频谱函数就是频域中位于该正弦波频率处的一对冲激函数.
np中用np.fft
模块可以做傅里叶变换
假设:关于一个变量的任意一个周期函数
周期为T的函数f(x)有:
然后因为有欧拉公式:
所以有:
假设一个函数(信号)是周期的,但是它的周期是无穷大,可以得出:
傅里叶正变换:
傅里叶反变换:
于是,我们可以利用傅里叶正变换变到分解状态(或者说频域),然后把它的分量分别处理,再利用反变换回去了.
实域变频域后,函数表现形式有了变化,各个分量有了频率,周期.
numpy中获取和处理频率的工具有
-
fftfreq(n[, d]) 获取连续傅里叶变换分量频率
-
rfftfreq(n[, d]) 获取离散傅里叶变换分量频率
-
fftshift(x[, axes]) 将0频分量移动到中心
-
ifftshift(x[, axes]) The inverse of fftshift. 上一操作的反操作
在时间上依次出现的数值序列,例如,{…,0.5,1,2,-1,0,5,…}.相邻两个数之间的时间间隔可以是相等的,也可以是不等的.在前一情况下,设时间间隔为T秒,则离散信号可用符号x(nT)来表示(图1).在间隔T归一化为1的条件下,T可以省略,即将x(nT)表示为x(n).x(n)既可表示整个序列,也可表示离散信号在nT瞬间的值.
简称DFT,
python的numpy里的fft模块就是用的这种变换
对于N点序列
其中i是虚数单位
其逆变换为:
方法 | 说明 |
---|---|
fft(a[, n, axis, norm]) | 一维空间离散傅里叶变换 |
ifft(a[, n, axis, norm]) | 一维空间离散傅里叶反变换 |
fft2(a[, s, axes, norm]) | 二维空间离散傅里叶变换 |
ifft2(a[, s, axes, norm]) | 二维空间离散傅里叶反变换 |
fftn(a[, s, axes, norm]) | N维空间离散傅里叶变换 |
ifftn(a[, s, axes, norm]) | N维空间离散傅里叶反变换 |
fft的参数是一个数组,这个数组可以理解为一个连续函数按一定周期采样的结果.而这个数组一般都是2的整数次幂.比如256,128,64这样
以下是标准傅里叶变换的例子
一维空间
我们以一个矩形波为例子
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
t = np.linspace(-1, 1, 128,endpoint=True)
tz = list(map(lambda x: 1 if (x > -0.5 and x<0.5) else 0,t))
plt.plot(t,tz)
plt.show()
sp = np.fft.fft(tz)
re = np.fft.ifft(sp)#傅里叶逆变换
plt.plot(t,re)
plt.show()
/Users/huangsizhe/Lib/conda/anaconda3/lib/python3.7/site-packages/numpy/core/numeric.py:538: ComplexWarning: Casting complex values to real discards the imaginary part
return array(a, dtype, copy=False, order=order)
freq = np.fft.fftfreq(t.shape[-1])#获取频率
plt.plot(freq, sp.real)
plt.show()
plt.plot(freq, sp.imag)
plt.show()
二维空间(常用图像处理)
a = np.mgrid[:5, :5][0]
a
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]])
np.fft.fft2(a)
array([[ 5.00000000e+01+0.00000000e+00j, 2.22044605e-15+0.00000000e+00j,
2.22044605e-15+0.00000000e+00j, 2.22044605e-15+0.00000000e+00j,
2.22044605e-15+0.00000000e+00j],
[-1.25000000e+01+1.72047740e+01j, -5.55111512e-16+7.64045449e-16j,
-5.55111512e-16+7.64045449e-16j, -5.55111512e-16+7.64045449e-16j,
-5.55111512e-16+7.64045449e-16j],
[-1.25000000e+01+4.06149620e+00j, -5.55111512e-16+1.80366664e-16j,
-5.55111512e-16+1.80366664e-16j, -5.55111512e-16+1.80366664e-16j,
-5.55111512e-16+1.80366664e-16j],
[-1.25000000e+01-4.06149620e+00j, -5.55111512e-16-1.80366664e-16j,
-5.55111512e-16-1.80366664e-16j, -5.55111512e-16-1.80366664e-16j,
-5.55111512e-16-1.80366664e-16j],
[-1.25000000e+01-1.72047740e+01j, -5.55111512e-16-7.64045449e-16j,
-5.55111512e-16-7.64045449e-16j, -5.55111512e-16-7.64045449e-16j,
-5.55111512e-16-7.64045449e-16j]])
n维空间
b = np.mgrid[:3, :3, :3][0]
b
array([[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]],
[[2, 2, 2],
[2, 2, 2],
[2, 2, 2]]])
np.fft.fftn(b, axes=(1, 2))
array([[[ 0.+0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j]],
[[ 9.+0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j]],
[[18.+0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j]]])
np.fft.fftn(b, (2, 2), axes=(0, 1))
array([[[ 2.+0.j, 2.+0.j, 2.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j]],
[[-2.+0.j, -2.+0.j, -2.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j]]])
[X, Y] = np.meshgrid(2 * np.pi * np.arange(200) / 12,
2 * np.pi * np.arange(200) / 34)
S = np.sin(X) + np.cos(Y) + np.random.uniform(0, 1, X.shape)
FS = np.fft.fftn(S)
plt.imshow(np.log(np.abs(np.fft.fftshift(FS))**2))
plt.show()
numpy中其他的傅里叶变换还有
实数快速傅里叶变换:
方法 | 说明 |
---|---|
rfft(a[, n, axis, norm]) | 实数输入的一维空间离散傅里叶变换 |
irfft(a[, n, axis, norm]) | 实数输入的一维空间离散傅里叶反变换 |
rfft2(a[, s, axes, norm]) | 实数输入的二维空间离散傅里叶变换 |
irfft2(a[, s, axes, norm]) | 实数输入的二维空间离散傅里叶反变换 |
rfftn(a[, s, axes, norm]) | 实数输入的N维空间离散傅里叶变换 |
irfftn(a[, s, axes, norm]) | 实数输入的N维空间离散傅里叶反变换 |
Hermitian傅里叶变换:
方法 | 说明 |
---|---|
hfft(a[, n, axis, norm]) | 计算实域中埃尔米特对称的信号的快速傅里叶变换 |
ihfft(a[, n, axis, norm]) | 计算实域中埃尔米特对称的信号的快速傅里叶反变换 |
他们用法与上面的相同就不一一描述了