SciPy fftpack(傅里叶变换)
章节
SciPy提供了fftpack模块,包含了傅里叶变换的算法实现。
傅立叶原理表明:任何连续测量的时序或信号,都可以表示为不同频率的正弦波信号的无限叠加。傅里叶变换把信号从时域变换到频域,以便对信号进行处理。傅里叶变换在信号与噪声处理、图像处理、音频信号处理等领域得到了广泛应用。
如需进一步了解傅里叶变换原理,可以参考相关资料。
快速傅里叶变换
计算机只能处理离散信号,使用离散傅里叶变换(DFT) 是计算机分析信号的基本方法。但是离散傅里叶变换的缺点是:计算量大,时间复杂度太高,当采样点数太高的时候,计算缓慢,由此出现了DFT的快速实现,即快速傅里叶变换FFT。
快速傅里叶变换(FFT)是计算量更小的离散傅里叶变换的一种实现方法,其逆变换被称为快速傅里叶逆变换(IFFT)。
示例
print(fft(np.array([4., 3., 5., 10., 5., 3.])))
先对数据进行fft变换,然后再ifft逆变换。
import numpy as np
#从fftpack中导入fft(快速傅里叶变化)和ifft(快速傅里叶逆变换)函数
from scipy.fftpack import fft,ifft
#创建一个随机值数组
x = np.array([1.0, 2.0, 1.0, -1.0, 1.5])
#对数组数据进行傅里叶变换
y = fft(x)
print('fft: ')
print(y)
print('\n')
#快速傅里叶逆变换
yinv = ifft(y)
print('ifft: ')
print(yinv)
print('\n')
输出
fft:
[ 4.5 +0.j 2.08155948-1.65109876j -1.83155948+1.60822041j
-1.83155948-1.60822041j 2.08155948+1.65109876j]
ifft:
[ 1. +0.j 2. +0.j 1. +0.j -1. +0.j 1.5+0.j]
可以看到fft,ifft返回的都是复数。ifft返回的结果中,复数的虚部都是0,实部与原始数据x一致。
这些点的频率无法计算,因为没有设置这N个点的时间长度。如不理解,不必深究,后面会介绍。
理解fft变换结果
我们知道,傅里叶变换把时域信号变为频域信号。在离散傅里叶变换中,频域信号由一系列不同频率的谐波(频率成倍数)组成。fft返回值是一个复数数组,每个复数表示一个正弦波。通常一个波形由振幅,相位,频率三个变量确定,可以从fft的返回值里,获取这些信息。
假设a是时域中的周期信号,采样频率为Fs,采样点数为N。如果A[N] = fft(a[N]),返回值A[N]是一个复数数组,其中:
- A[0]表示频率为0hz的信号,即直流分量。
- A[1:N/2]包含正频率项,A[N/2:]包含负频率项。正频率项就是转化后的频域信号,通常我们只需要正频率项,即前面的n/2项,负频率项是计算的中间结果(正频率项的镜像值)。
- 每一项的频率计算:假设A[i]为数组中的元素,表示一个波形,该波形的频率 = i * Fs / N
- A[i] = real + j * imag,是一个复数,相位就是复数的辐角,相位 = arg(real/imag)
- 类似的,振幅就是复数的模,振幅 = sqrt(real2+imag2)。但是fft的返回值的模是放大值,直流分量的振幅放大了N倍,弦波分量的振幅放大了N/2倍。
频率分辨率
频率分辨率是离散傅里叶变换(DFT)频域相邻刻度之间的实际频率之差。采样时,数据采样了T秒(T = 采样点数N / 采样频率Fs),信号的成分中周期最大也就是T秒,最低频率即“基频”就等于1 / T,也就是Fs / N,这就是频率分辨率。基频 =Fs / N,各个谐波的频率就是i * Fs / N,这个公式用于计算各个波形的频率。
示例
import numpy as np
from scipy.fftpack import fft
# 采样点数
N = 4000
# 采样频率 (根据采样定理,采样频率必须大于信号最高频率的2倍,信号才不会失真)
Fs = 8000
x = np.linspace(0.0, N/Fs, N)
# 时域信号,包含:直流分量振幅1.0,正弦波分量频率100hz/振幅2.0, 正弦波分量频率150Hz/振幅0.5/相位np.pi
y = 1.0 + 2.0 * np.sin(100.0 * 2.0*np.pi*x) + 0.5*np.sin(150.0 * 2.0*np.pi*x + np.pi)
# 进行fft变换
yf = fft(y)
# 获取振幅,取复数的绝对值,即复数的模
abs_yf = np.abs(yf)
# 获取相位,取复数的角度
angle_y=np.angle(yf)
# 直流信号
print('\n直流信号')
print('振幅:', abs_yf[0]/N) # 直流分量的振幅放大了N倍
# 100hz信号
index_100hz = 100 * N // Fs # 波形的频率 = i * Fs / N,倒推计算索引:i = 波形频率 * N / Fs
print('\n100hz波形')
print('振幅:', abs_yf[index_100hz] * 2.0/N) # 弦波分量的振幅放大了N/2倍
print('相位:', angle_y[index_100hz])
# 150hz信号
index_150hz = 150 * N // Fs # 波形的频率 = i * Fs / N,倒推计算索引:i = 波形频率 * N / Fs
print('\n150hz波形')
print('振幅:', abs_yf[index_150hz] * 2.0/N) # 弦波分量的振幅放大了N/2倍
print('相位:', angle_y[index_150hz])
print('100hz与150hz相位差:', angle_y[index_150hz] - angle_y[index_100hz])
print('\n')
输出
直流信号
振幅: 1.0
100hz波形
振幅: 1.9989359813189005
相位: -1.5315264186250062
150hz波形
振幅: 0.5008489983048182
相位: 1.6297011890497097
100hz与150hz相位差: 3.161227607674716
可以看到,正弦波的相位不一定从0开始,但波形之间的相位差确实s约等于一个pi(值跟采样频率与采样点数有关系)。
离散余弦变换(DCT)
由于许多要处理的信号都是实信号,在使用FFT时,对于实信号,傅立叶变换的共轭对称性导致在频域中有一半的数据冗余。
离散余弦变换(DCT)是对实信号定义的一种变换,变换后在频域中得到的也是一个实信号,相比离散傅里叶变换DFT而言, DCT可以减少一半以上的计算。DCT还有一个很重要的性质(能量集中特性):大多书自然信号(声音、图像)的能量都集中在离散余弦变换后的低频部分,因而DCT在(声音、图像)数据压缩中得到了广泛的使用。由于DCT是从DFT推导出来的另一种变换,因此许多DFT的属性在DCT中仍然是保留下来的。
SciPy.fftpack中,提供了离散余弦变换(DCT)与离散余弦逆变换(IDCT)的实现。
示例
import numpy as np
from scipy.fftpack import dct,idct
y = dct(np.array([4., 3., 5., 10., 5., 3.]))
print(y)
输出
[ 60. -3.48476592 -13.85640646 11.3137085 6.
-6.31319305]
离散余弦逆变换(idct),是离散余弦变换(DCT)的反变换。
示例
import numpy as np
from scipy.fftpack import dct,idct
y = idct(np.array([4., 3., 5., 10., 5., 3.]))
print(y)
输出
[ 39.15085889 -20.14213562 -6.45392043 7.13341236 8.14213562
-3.83035081]
SciPy fftpack(傅里叶变换)的更多相关文章
- scipy.fftpack fft
from scipy.fftpack import fft SciPy提供fftpack模块,可让用户计算快速傅立叶变换 例子: >>> a = np.arange(1,5) > ...
- Difference between scipy.fftpack and numpy.fft
scipy.fftpack 和 numpy.fft 的区别 When applying scipy.fftpack.rfft and numpy.fft.rfft I get the followin ...
- 1.5 Scipy:高级科学计算
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...
- SciPy 信号处理
章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...
- SciPy 统计
章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...
- SciPy 线性代数
章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...
- SciPy 图像处理
章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...
- SciPy 优化
章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...
- SciPy 积分
章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...
随机推荐
- AngularJS学习:第一个demo
1. 引入angular.js 相应版本下载地址: https://code.angularjs.org/ 2. 编写html <!DOCTYPE html> <html> & ...
- leetcode 0207
目录 ✅ 561. 数组拆分 I ✅ 1025. 除数博弈 聪明的数学归纳法: 动态规划又来了(没理解,todo 0207): ✅ 557. 反转字符串中的单词 III py 中的 字符 split ...
- stm32CubeMx lwip + freeRTOS
MCU: STM32F429IGT6 工具:STM32CubeMx 版本号 5.0.0 Keil uVersion5 目的:使用LWIP 实现简单的网络连通 一 简介 LWIP(Light Wei ...
- [ DLPytorch ] 文本分类&图像增强
图像增强 图像增广(image augmentation)技术通过对训练图像做一系列随机改变,来产生相似但又不同的训练样本,从而扩大训练数据集的规模.图像增广的另一种解释是,随机改变训练样本可以降低模 ...
- 简单bat脚本
hwf.bat: set GAP_HOME=%~dp0\.. ::copy "%JAVA_HOME%\bin\javaw.exe" "%JAVA_HOME%\bin\HW ...
- 在visual studio中快速添加代码段
昨天我在网课上,看到老师输入#2之后,立马就出现了一堆代码. 我于是赶紧打开自己的visual studio尝试一下,并没有任何反应. 上网查找,发现visual studio有自定义代码段的功能. ...
- SpringBoot集成Freemarker前端模板
1.在pom.xml中引入freemarker的jar包 <dependency> <groupId>org.springframework.boot</groupId& ...
- 乒乓球(0)<P2003_1>
乒乓球(table.cpp/c/pas) [问题背景]国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及.其中11分制改革引起了很大的争议,有一部分球员因为无法适应 ...
- 第一周之Hadoop学习(一)
首先根据网上的教程得搭建一个linux的环境,所以第一部分是下载虚拟机的过程. 参考博客:https://blog.csdn.net/hliq5399/article/details/78193113 ...
- Qt5.5 使用smtp发邮件的各种坑
本人刚开始学习C++,用的是Qt5.5的IED,经过了两天的学习和查找资料,终于成功发了第一封邮件.以163邮箱为例,简单总结一下. 1.设置邮箱 这一步比较关键,要开通smtp服务,在开通的过程中会 ...