目录

  • 频谱分析
  • FFT频谱分析原理
  • 下面就用python案例进行说明
    • 案例1
    • 案例2
  • 短时傅里叶变换STFT

本分享为脑机学习者Rose整理发表于公众号:脑机接口社区.QQ交流群:941473018

EEG信号是大脑神经元电活动的直接反应,包含着丰富的信息,但EEG信号幅值小,其中又混杂有噪声干扰,如何从EEG信号中抽取我们所感兴趣的信号是一个极为重要的问题。自1932年Dietch首先提出用傅里叶变换方法来分析EEG信号,该领域相继引入了频域分析、时域分析等脑电分析的经典方法。

频谱分析

下面是一组用于描述和解释信号属性的常用量(matlab的常见形式,python中的常见形式也类似):
x: 采样的数据;
n=length(x): 样本数量;
fs: 采样频率(每单位时间或空间的样本数)(单位常用:赫兹Hz);
dt=1/fs :每样本的时间或空间增量(如果是时间上的增量,则又称:采样间隔或采样步长,单位常用:s);
t=(0:n-1)/fs : 数据的时间或空间范围;
y=fft(x) : 数据的离散傅里叶变换(DFT);
abs(y) :DFT的振幅;
(abs(y).^2)/n :DFT的幂;
fs/n : 频率增量;
f=(0:n-1) * (fs/n) : 频率范围;
fs/2 :Nyquist频率(频率范围的中点);

FFT频谱分析原理

频谱分析是一种将复噪声号分解为较简单信号的技术。真实世界中的信号可能由多种简单信号叠加而成。找出一个信号在不同频率下的信息(可能是幅度、功率、强度或相位等)的作法就是频谱分析。

采样定理:采样频率要大于信号频率的两倍。
N个采样点经过FFT变换后得到N个点的以复数形式记录的FFT结果。

假设采样频率为Fs,采样点数为N。那么FFT运算的结果就是N个复数(或N个点),每一个复数就对应着一个频率值以及该频率信号的幅值和相位。
第一个点对应的频率为0Hz(即直流分量),最后一个点N的下一个点对应采样频率Fs。其中任意一个采样点n所代表的信号频率:

这表明,频谱分析得到的信号频率最大为 (N-1)*Fs/N,对频率的分辨能力是Fs/N。采样频率和采样时间制约着通过FFT运算能分析得到的信号频率上限,同时也限定了分析得到的信号频率的分辨率。

每一个复数的模值对应该点所对应的频率值的幅度特性,具体的定量关系如下:
假设信号由以下周期的原始信号叠加而成:

那么,在经过FFT分析后得到的第一个点的模值是A1的N倍,而且只有在FFT结果点对应的频率在ω2,ω3时,其模值才明显放大,在其他频率点,模值接近于0。在这些模值明显放大的点中,除第一个点之外的其它点模值是相应信号幅值的N/2倍。

每个复数的相位就是在该频率值下信号的相位:φ2,φ3。
FFT结果有对称性,通常我们只是用前半部分的结果,也就是小于采样频率一半的结果。同时也只有采样频率一半以内、具有一定幅值的信号频率才是真正的信号频率。

下面就用python案例进行说明

案例1

import numpy as np
import pylab as pl
import math# 采样频率
fs=1048
# 采样步长
t = [x/1048.0 for x in range(1048)]
"""
设计的采样值
假设信号y由4个周期信号叠加所得,如下所示
"""
y = [ 3.0 * np.cos(2.0 * np.pi * 50 * t0 - np.pi * 30/180)+ 1.5 * np.cos(2.0 * np.pi * 75 * t0 + np.pi * 90/180)+  1.0 * np.cos(2.0 * np.pi * 150 * t0 + np.pi * 120/180)+  2.0 * np.cos(2.0 * np.pi * 220 * t0 + np.pi * 30/180)for t0 in t ]
pl.plot(t,y)
pl.xlabel('time(s)')
pl.title("original signal")
pl.show()

"""
现在对上述信号y在0-1秒时间内进行频谱分析,本案例中采样频率为1048Hz,即单位时间内采样点数为1048
"""
# 采样点数
N=len(t)
# 采样频率
fs=1048.0
# 分辨率
df = fs/(N-1)
# 构建频率数组
f = [df*n for n in range(0,N)]
Y = np.fft.fft(y)*2/N  #*2/N 反映了FFT变换的结果与实际信号幅值之间的关系
absY = [np.abs(x) for x in Y]      #求傅里叶变换结果的模pl.plot(f,absY)
pl.xlabel('freq(Hz)')
pl.title("fft")
pl.show()

案例2

from scipy.fftpack import fft, fftshift, ifft
from scipy.fftpack import fftfreq
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline"""
t_s:采样周期
t_start:起始时间
t_end:结束时间
"""
t_s = 0.01
t_start = 0.5
t_end = 5
t = np.arange(t_start, t_end, t_s)f0 = 5
f1 = 20# 绘制图表
plt.figure(figsize=(10, 12))# 构建原始信号序列
y = 1.5*np.sin(2*np.pi*f0*t) + 3*np.sin(2*np.pi*20*t) + np.random.randn(t.size)
ax=plt.subplot(511)
ax.set_title('original signal')
plt.tight_layout()
plt.plot(y)"""
FFT(Fast Fourier Transformation)快速傅里叶变换
"""
Y = fft(y)
ax=plt.subplot(512)
ax.set_title('fft transform')
plt.plot(np.abs(Y))"""
Y = fftshift(X) 通过将零频分量移动到数组中心,重新排列傅里叶变换 X。
"""
shift_Y = fftshift(Y)
ax=plt.subplot(513)
ax.set_title('shift fft transform')
plt.plot(np.abs(shift_Y))"""
得到正频率部分
"""
pos_Y_from_fft = Y[:Y.size//2]
ax=plt.subplot(514)
ax.set_title('fft transform')
plt.tight_layout()
plt.plot(np.abs(pos_Y_from_fft))"""
直接截取 shift fft结果的前半部分
"""
pos_Y_from_shift = shift_Y[shift_Y.size//2:]
ax=plt.subplot(515)
ax.set_title('shift fft cut')
plt.plot(np.abs(pos_Y_from_shift))
plt.show()

代码来源于网络,本文对代码进行注释并整理

短时傅里叶变换STFT

众所周知,傅里叶变换的快速算法FFT可以用来对信号的频域特征进行分析,然而,FFT仅能用于平稳信号的分析,对于非平稳信号,则需要采用短时傅里叶变换(STFT)进行分析。

对于非平稳信号,短时傅里叶变换所采用的策略是在信号上面加窗,一般是hamming窗,当然也可以是其它类型的窗函数,加窗之后的信号被分割为一组短长度子序列,子序列可以近似的看为平稳序列,可以用傅里叶变换的方式去进行分析,这也是短时傅里叶变换的精髓所在。

用STFT进行脑电信号分析一般有两种思路,第一种是用STFT来分离EEG信号的波段,从而求得每一个波段的能量作为特征(alpha、beta、theta、gamma、deta)。第二种是利用STFT计算功率谱密度作为特征,功率谱密度(PSD)特征可以针对整个信号子序列也可以针对子序列中特定的波段来计算。这两种思路中,第二种思路用的比较广,下面对其进行说明。

matlab中进行STFT的函数为spectrogram,计算功率谱密度(PSD)时使用如下格式:

[S,F,T,P]=spectrogram(x,window,noverlap,nfft,fs)

其中,S为输入信号x的短时傅里叶变换,F为频率向量,T为时间向量,P为功率谱密度矩阵,x为输入信号,window为时间窗,noverlap为overlap的点数,如果为0就是没有overlap,nfft为DFT的点数,fs为采样频率。其中,F向量的维度和P的行数一致,可以根据F向量来选取特定波段的PSD,还可以将alpha、beta、theta、gamma、deta这几个波段分别分为几个窄波段,提取窄带PSD。

参考:
https://blog.csdn.net/lbaihao/article/details/81280030
https://blog.csdn.net/weiwei9363/article/details/86545691
https://blog.csdn.net/qrlhl/article/details/72155395
脑电信号分析方法与脑机接口技术
信号处理之频谱原理与python实现

本文章由脑机学习者Rose笔记分享,QQ交流群:941473018
更多分享,请关注公众号

信号处理之频谱原理与python实现相关推荐

  1. 倒频谱原理与python实现

    目录 倒频谱定义 倒频谱python案例 本教程为脑机学习者Rose发表于公众号:脑机接口社区 .QQ交流群:903290195 倒频谱定义 倒频谱可以分析复杂频谱图上的周期结构,分离和提取在密集调频 ...

  2. fft 相位谱_信号处理之功率谱原理与python实现

    点击上面"脑机接口社区"关注我们 更多技术干货第一时间送达 功率谱图又叫功率谱密度图 功率谱是功率谱密度函数的简称,它定义为单位频带内的信号功率.它表示了信号功率随着频率的变化情况 ...

  3. python实现守护进程_守护进程原理及Python实现

    守护进程原理及Python实现 守护进程,不依赖于终端,在后台运行的程序,通常称为daemon(ˈdiːmən或ˈdeɪmən). 一些常见的Linux软件通常都是已守护进程的方式运行,比如: ngi ...

  4. java寻优算法_模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径...

    模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...

  5. python gdbt+fm_GBDT回归的原理及Python实现

    提到GBDT回归相信大家应该都不会觉得陌生(不陌生你点进来干嘛[捂脸]),本文就GBDT回归的基本原理进行讲解,并手把手.肩并肩地带您实现这一算法. 完整实现代码请参考本人的p...哦不是...git ...

  6. 手把手教你EMD算法原理与Python实现(更新)

    Rose今天主要介绍一下EMD算法原理与Python实现.关于EMD算法之前介绍过<EMD算法之Hilbert-Huang Transform原理详解和案例分析>, SSVEP信号中含有自 ...

  7. 冲量(momentum)的原理与Python实现

    冲量(momentum)的原理与Python实现 前言 参考:https://www.jianshu.com/p/58b3fe300ecb 梯度下降法(Gradient Descent)是机器学习中最 ...

  8. python实现逻辑回归的流程_逻辑回归原理及其python实现

    September 28, 2018 7 min to read 逻辑回归原理及其python实现 原理 逻辑回归模型: $h_{\theta}(x)=\frac{1}{1+e^{-{\theta}^ ...

  9. 典型相关分析(cca)原理_CCA典型关联分析原理与Python案例

    文章来源于"脑机接口社区" CCA典型关联分析原理与Python案例​mp.weixin.qq.com Rose今天分享一下CCA的相关原理以及Python应用,CCA在EEG等脑 ...

最新文章

  1. JAVA EE 中之AJAX 无刷新地区下拉列表三级联动
  2. python all()函数 (判断可迭代对象中是否全为True)
  3. DCMTK:DcmFloatingPointDouble类的测试程序
  4. VC下几种转换为UNICODE字符串的方法
  5. SAP License:分摊、分配、定期重过账
  6. python软件-Python软件下载|Python最新版本v3.5.1 下载_当游网
  7. PHP可变变量的简单使用
  8. java反射父类_Java反射获取对象全部属性,包括父类属性
  9. 2021-08-16 WPF控件专题 StackPanel 控件详解
  10. 康佳电视软件测试工程师,康佳电视怎么样之康佳55吋曲面人工智能电视试用测评...
  11. 龙格库塔(Runge-Kutta)法求四元数微分方程
  12. php工作表,工作表的标签在工作表的什么地方
  13. 【MySQL(七)】脏页
  14. 汇编语言程序设计51单片机
  15. Pomelo MMORPG
  16. linux查看80端口连接ip,Linux通过netstat命令查看80端口连接数的方法
  17. 【高级微观经济学】厂商理论:生产技术与生产函数
  18. 收藏 | Android开发从入门到精通系列书籍资料最全攻略!!!(最新更新)
  19. 华为交换机路由器命名规则
  20. 华硕主板设置定时自动开机

热门文章

  1. 解决 .net core 中 nuget 包版本冲突问题
  2. npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! test_vue_0613@1.0.0 dev: 错误的解决方法
  3. Rails 4:如何使用带有turbo-links的$(document).ready()
  4. 向流程组的所有成员发送信号的最佳方法是什么?
  5. 在Objective-C中创建一个抽象类
  6. 如何在Python中使用“ with open”打开多个文件?
  7. 安装SaltStack
  8. 据说这是个电子元器件采购的春天,我们该如何把握机遇?
  9. 在区块链上表白——使用C#将一句话放入比特币的区块链上
  10. webService——学习(3):使用JDK开发webService