微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何有效地生成和连接频谱图

如何解决如何有效地生成和连接频谱图

我正在研究与信号处理相关的问题。我有一个超过 2000 个 EEG 信号的数据集。每个 EEG 信号由一个 2D Numpy 数组 (19 x 30000) 表示。阵列的每一行都是信号的通道之一。我要做的是在这些单独的通道(行)上找到频谱图并将它们垂直连接起来。这是我目前编写的代码

raw = np.load('class_1_ar/'+filename)

images = []

for i in range(19):    
    print(i,end=" ")
    spec,freq,t,im = plt.specgram(raw[i],Fs=100,nfft=100,noverlap=50)
    plt.axis('off')
    figure = plt.gcf()
    figure.set_size_inches(12,1)

    figure.canvas.draw()
    img = np.array(figure.canvas.buffer_rgba())
    img = cv2.cvtColor(img,cv2.COLOR_RGBA2BGRA)

    b = figure.axes[0].get_window_extent()
    img = np.array(figure.canvas.buffer_rgba())
    img = img[int(b.y0):int(b.y1),int(b.x0):int(b.x1),:]
    img = cv2.cvtColor(img,cv2.COLOR_RGBA2BGRA)
    
    images.append(img)

base = cv2.vconcat(images)
cv2.imwrite('class_1_sp/'+filename[:-4]+'.png',base)


c -= 1
print(c)

这是我的输出

enter image description here

但是,该过程需要花费太多时间来处理。前 200 个样本的处理耗时近 8 小时。

我的问题是,我该怎么做才能让它更快?

解决方法

正如其他人所说,通过 matplotlib 的开销可能会减慢速度。最好只用 scipy.signal.spectrogram 计算(而不是绘制)频谱图。此函数直接将频谱图作为 2D numpy 数组返回,这样您就没有将其从画布中取出的迂回步骤。请注意,这确实意味着您必须自己将频谱图输出映射到像素强度。这样做时,请注意 scipy.signal.spectrogram 将频谱图返回为幂,而不是分贝,因此您可能希望对结果执行 10*np.log10(Sxx)(另请参阅 scipy.signal.spectrogram compared to matplotlib.pyplot.specgram)。

撇开绘图不谈,计算频谱图的瓶颈操作是 FFT。与使用 100 个样本的变换大小不同,128 或其他一些 2 的幂更有效。对于 scipy.signal.spectrogram,这是通过设置 nfft=128 来完成的。请注意,您可以设置 nperseg=100nfft=128,以便每个段仍使用 100 个样本,但在执行 FFT 之前将零填充为 128。另一种想法是:如果 raw 是 64 位浮点数,则将其转换为 32 位可能会有所帮助:raw = np.load(...).astype(np.float32)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。