如何将 matplotlib 频谱图图像转换为火炬张量

Posted

技术标签:

【中文标题】如何将 matplotlib 频谱图图像转换为火炬张量【英文标题】:How to convert a matplotlib spectrogram image into a torch tensor 【发布时间】:2022-01-20 15:33:46 【问题描述】:
import numpy as np
from numpy import asarray
from matplotlib import pyplot as plt
import torch

# generate a signal
fs = 50 # sampling freq
ts = np.arange(0, 10, 1/fs) # times at which signal is sampled
s1 = np.sin(2 * np.pi * 2 * ts) # 2 hz
s2 = np.sin(2 * np.pi * 3 * ts) # 3 hz
s3 = np.sin(2 * np.pi * 6 * ts) # 6 hz
s = s1 + s2 + s3 # aggregate signal

# generate specgram
spectrum, freqs, t, im = plt.specgram(s, Fs=fs, xextent=((0, len(s)/fs)))

# convert matplotlib image to torch tensor
# bypassing the numpy part would be even better!
torch_tensor = torch.from_numpy(asarray(im, np.float32))

print(torch_tensor)

>>> TypeError: float() argument must be a string or a number, not 'AxesImage'

我应该补充一点,'spectrum' 变量是我正在寻找的东西,除了我对它有点困惑,因为它只有两列时间,而且我认为 specgram 图像有不止两列时间步长。如果有办法使用光谱变量将整个图像表示为火炬张量,那么这对我也有用。

【问题讨论】:

【参考方案1】:

plt.specgram 返回spectrum 变量中的频谱图。这意味着您需要将该变量传递给torch.from_numpy 函数。此外,根据this,specgram 显示10*log10(spectrum),这意味着您可能希望执行该操作,而不是将specgram 显示的结果与您的张量图进行比较。见以下代码:

import numpy as np
from numpy import asarray
import numpy as np
from matplotlib import pyplot as plt
import torch

# generate a signal
fs = 50 # sampling freq
ts = np.arange(0, 10, 1/fs) # times at which signal is sampled
s1 = np.sin(2 * np.pi * 2 * ts) # 2 hz
s2 = np.sin(2 * np.pi * 3 * ts) # 3 hz
s3 = np.sin(2 * np.pi * 6 * ts) # 6 hz
s = s1 + s2 + s3 # aggregate signal

# generate specgram
ax1=plt.subplot(121)
ax1.set_title('Specgram image')
spectrum, freqs, t, im = ax1.specgram(s, Fs=fs, xextent=((0, len(s)/fs)))
ax1.axis('tight')

torch_tensor = torch.from_numpy(spectrum)

#Plot torch tensor variable
ax2=plt.subplot(122)
ax2.set_title('Torch tensor image')
ax2.imshow(10*np.log10(torch_tensor),origin='lower left',extent=[0,10,0,25])
ax2.axis('tight')

plt.show()

输出给出:

【讨论】:

你知道有没有办法将“火炬张量图像”设置为对象?类似specgram_object = ax2.imshow(10*np.log10(torch_tensor)...) 对象是 np.array 或 torch.tensor 你可以使用:torch_tensor = torch.from_numpy(10*np.log10(spectrum)) imshow 返回一个 AxesImage 实例,所以我认为您不能将其转换为 numpy 数组或 torch 张量。即使你可以,我也不确定它是否意味着什么,因为它处理的是与显示图像相关的属性,而不是你正在绘制的数组 问题是我想要整个“specgram image”。您建议的 torch_tensor 尺寸为 (129,2),而图像尺寸为 (375,264) 维度 (129,2) 来自您计算频谱图的方式。我展示的两个图都只有 2 列和 129 行。如果您想要更多的时间窗口,您可能需要产生更长的信号或更改频谱图的选项

以上是关于如何将 matplotlib 频谱图图像转换为火炬张量的主要内容,如果未能解决你的问题,请参考以下文章

如何将 .tif PIL 图像转换为火炬张量?

如何将 Librosa 频谱图保存为特定尺寸的图像?

如何使用 matplotlib/numpy 将数组保存为灰度图像?

Python如何将RGB图像转换为Pytho灰度图像?

在matplotlib中绘制频谱图颜色条的问题[重复]

有没有办法直接将频谱图转换为 MFCC?