脑电信号频谱图的理想参数是什么?
what is the ideal parameters for spectrogram of eeg signal?
我正在尝试绘制采样率为 1000Hz 并使用 14 - 70 Hz 带通滤波的 EEG 信号的频谱图,信号长度为 440(而且我无法增加信号)。信号(数据link here)看起来像这样:
我尝试了以下参数值来绘制频谱图:
#plot spectrogram for a single channel
fs = 1000
nperseg = 200
plt.figure(figsize=(10,10))
f, t, Sxx = signal.spectrogram(Oz[0], fs, nperseg=nperseg, noverlap=nperseg-1)
plt.pcolormesh(t, f, Sxx, shading='gouraud')
plt.ylim([0,70])
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()
给出了这样的情节:
任何人都可以建议理想的参数设置来提高频谱图分辨率吗?
编辑:
为了增强我的查询,我想知道 nperseg、nfft、window_size[ 等参数的值=35=]和noverlap决定了。如果我有 采样率 (fs) 和 信号长度 .
,它们将如何关联
我不知道你期望的输出是什么,但可以尝试更改 pcolormesh 的阴影。您还可以将 window 添加到频谱图的计算中。您还可以使用 cmap 更改用于表示频谱图的颜色。
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal
my_data = np.genfromtxt('signal_value_spectro.csv', delimiter=',',skip_header=0)
Oz=my_data[1:,0]
fs = 1000
t = np.arange(len(Oz))/fs
# nperseg = len(Oz[0])-1
nperseg=50
f50, t50, Sxx_50 = signal.spectrogram(Oz, fs, nperseg=nperseg , noverlap=nperseg-1,window=signal.get_window('hann',nperseg))
nperseg=150
f150, t150, Sxx_150 = signal.spectrogram(Oz, fs, nperseg=nperseg , noverlap=nperseg-1,window=signal.get_window('hann',nperseg))
nperseg=350
f350, t350, Sxx_350 = signal.spectrogram(Oz, fs, nperseg=nperseg , noverlap=nperseg-1,window=signal.get_window('hann',nperseg))
plt.figure(figsize=(10,10))
plt.subplot(211)
plt.plot(np.arange(len(Oz))/fs,Oz)
plt.subplot(234)
plt.pcolormesh(t50, f50, Sxx_50, shading='auto',cmap = 'inferno')
plt.ylim([0,70])
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec], nperseg = 50')
plt.subplot(235)
plt.pcolormesh(t150, f150, Sxx_150, shading='auto',cmap = 'inferno')
plt.ylim([0,70])
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec], nperseg = 150')
plt.subplot(236)
plt.pcolormesh(t350, f350, Sxx_350, shading='auto',cmap = 'inferno')
plt.ylim([0,70])
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec], nperseg = 350')
plt.show()
但是你的大问题是信号的长度。您受到 time-frequency 分辨率的限制。基本上,您将获得的频带数是 nperseg 的长度除以 2,分布在区间 [0, FS/2] 上。由于您的信号是 440 个样本,因此 nperseg 应该是情人。但是如果你将 nperseg 增加太多,你会失去时间分辨率。例如nperseg = 50,则有390个时间点,但id nperseg = 350,则只有90个时间点。
文档中提供了信息 https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.spectrogram.html
我正在尝试绘制采样率为 1000Hz 并使用 14 - 70 Hz 带通滤波的 EEG 信号的频谱图,信号长度为 440(而且我无法增加信号)。信号(数据link here)看起来像这样:
我尝试了以下参数值来绘制频谱图:
#plot spectrogram for a single channel
fs = 1000
nperseg = 200
plt.figure(figsize=(10,10))
f, t, Sxx = signal.spectrogram(Oz[0], fs, nperseg=nperseg, noverlap=nperseg-1)
plt.pcolormesh(t, f, Sxx, shading='gouraud')
plt.ylim([0,70])
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()
给出了这样的情节:
任何人都可以建议理想的参数设置来提高频谱图分辨率吗?
编辑: 为了增强我的查询,我想知道 nperseg、nfft、window_size[ 等参数的值=35=]和noverlap决定了。如果我有 采样率 (fs) 和 信号长度 .
,它们将如何关联我不知道你期望的输出是什么,但可以尝试更改 pcolormesh 的阴影。您还可以将 window 添加到频谱图的计算中。您还可以使用 cmap 更改用于表示频谱图的颜色。
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal
my_data = np.genfromtxt('signal_value_spectro.csv', delimiter=',',skip_header=0)
Oz=my_data[1:,0]
fs = 1000
t = np.arange(len(Oz))/fs
# nperseg = len(Oz[0])-1
nperseg=50
f50, t50, Sxx_50 = signal.spectrogram(Oz, fs, nperseg=nperseg , noverlap=nperseg-1,window=signal.get_window('hann',nperseg))
nperseg=150
f150, t150, Sxx_150 = signal.spectrogram(Oz, fs, nperseg=nperseg , noverlap=nperseg-1,window=signal.get_window('hann',nperseg))
nperseg=350
f350, t350, Sxx_350 = signal.spectrogram(Oz, fs, nperseg=nperseg , noverlap=nperseg-1,window=signal.get_window('hann',nperseg))
plt.figure(figsize=(10,10))
plt.subplot(211)
plt.plot(np.arange(len(Oz))/fs,Oz)
plt.subplot(234)
plt.pcolormesh(t50, f50, Sxx_50, shading='auto',cmap = 'inferno')
plt.ylim([0,70])
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec], nperseg = 50')
plt.subplot(235)
plt.pcolormesh(t150, f150, Sxx_150, shading='auto',cmap = 'inferno')
plt.ylim([0,70])
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec], nperseg = 150')
plt.subplot(236)
plt.pcolormesh(t350, f350, Sxx_350, shading='auto',cmap = 'inferno')
plt.ylim([0,70])
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec], nperseg = 350')
plt.show()
但是你的大问题是信号的长度。您受到 time-frequency 分辨率的限制。基本上,您将获得的频带数是 nperseg 的长度除以 2,分布在区间 [0, FS/2] 上。由于您的信号是 440 个样本,因此 nperseg 应该是情人。但是如果你将 nperseg 增加太多,你会失去时间分辨率。例如nperseg = 50,则有390个时间点,但id nperseg = 350,则只有90个时间点。
文档中提供了信息 https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.spectrogram.html