将浮点数组渲染为 24 位 RGB 图像(例如使用 PIL)
Rendering a float array to 24-bit RGB image (using PIL for example)
x
是一个 numpy.float32
数组,值从 -200
到 0
。这些是 dB(分贝)值。
当我这样做时(按照推荐 here):
Image.fromarray(x, mode='F')
我得到灰度图像或有时接近黑色的图像。
如何将 [-200, 0] 中的浮点数映射到可以使用 Python 模块 PIL 读取的 24 位 RGB 字节数组(使用颜色图) Image.fromarray(x, mode='RGB')
?
编辑:
所需的 .wav 音频文件是 here, for which we want to plot the spectrogram。
这是一些要测试的代码:
import scipy, numpy as np
import scipy.io.wavfile as wavfile
import numpy as np
from PIL import Image
def stft(x, fftsize=1024, overlap=4):
hop = fftsize / overlap
w = scipy.hanning(fftsize+1)[:-1]
return np.array([np.fft.rfft(w*x[i:i+fftsize]) for i in range(0, len(x)-fftsize, hop)])
def dB(ratio):
return 20 * np.log10(ratio+1e-10)
def magnitudedB(frame, fftsize=1024):
w = scipy.hanning(fftsize+1)[:-1]
ref = np.sum(w) / 2
return dB(np.abs(frame) / ref)
sr, x = wavfile.read('test.wav')
x = np.float32(x) / 2**15
s = magnitudedB(stft(x)).astype(np.float32).transpose()[::-1,]
print "Max %.1f dB, Min %.1f dB" % (np.max(s), np.min(s))
im = Image.fromarray(s+200, mode='F')
im.show()
备注:
色图是灰度的,如何得到另一个色图?喜欢 this one
我唯一的要求是输出图像可以读入 Tkinter 框架/canvas(它适用于 PIL 的 im = Image.fromarray(...)
然后 ImageTk.PhotoImage(image=im)
) 或 wxPython 框架 / canvas.
我在文档中找不到有关 mode='F' 的任何详细信息,但我希望它采用 0.0 - 1.0 范围内的像素值。您的值完全低于该范围,因此是黑色图像;你需要改造它们。
获取彩色图像(而不是灰度图)需要模式='P',这需要您将数据转换为字节数组。
要使用颜色图绘制图像,我建议您使用 matplotlib.pyplot.imshow。
对您的 test.wav
文件执行此操作的结果如下所示:
有关使用 python 创建音频频谱图的更多详细信息,您可以阅读更多相关内容 here
根据答案here, you can use matplotlib colormaps 在转换为图像之前转换 numpy 数组。
#im = Image.fromarray(s+200, mode='F')
from matplotlib import cm
s = (s + 200)/200.0 # input data should range from 0-1
im = Image.fromarray(cm.jet(s, bytes=True))
im.show()
您可能应该根据您的 min/max 值适当地设置缩放比例。
示例输出:
x
是一个 numpy.float32
数组,值从 -200
到 0
。这些是 dB(分贝)值。
当我这样做时(按照推荐 here):
Image.fromarray(x, mode='F')
我得到灰度图像或有时接近黑色的图像。
如何将 [-200, 0] 中的浮点数映射到可以使用 Python 模块 PIL 读取的 24 位 RGB 字节数组(使用颜色图) Image.fromarray(x, mode='RGB')
?
编辑:
所需的 .wav 音频文件是 here, for which we want to plot the spectrogram。
这是一些要测试的代码:
import scipy, numpy as np
import scipy.io.wavfile as wavfile
import numpy as np
from PIL import Image
def stft(x, fftsize=1024, overlap=4):
hop = fftsize / overlap
w = scipy.hanning(fftsize+1)[:-1]
return np.array([np.fft.rfft(w*x[i:i+fftsize]) for i in range(0, len(x)-fftsize, hop)])
def dB(ratio):
return 20 * np.log10(ratio+1e-10)
def magnitudedB(frame, fftsize=1024):
w = scipy.hanning(fftsize+1)[:-1]
ref = np.sum(w) / 2
return dB(np.abs(frame) / ref)
sr, x = wavfile.read('test.wav')
x = np.float32(x) / 2**15
s = magnitudedB(stft(x)).astype(np.float32).transpose()[::-1,]
print "Max %.1f dB, Min %.1f dB" % (np.max(s), np.min(s))
im = Image.fromarray(s+200, mode='F')
im.show()
备注:
色图是灰度的,如何得到另一个色图?喜欢 this one
我唯一的要求是输出图像可以读入 Tkinter 框架/canvas(它适用于 PIL 的
im = Image.fromarray(...)
然后ImageTk.PhotoImage(image=im)
) 或 wxPython 框架 / canvas.
我在文档中找不到有关 mode='F' 的任何详细信息,但我希望它采用 0.0 - 1.0 范围内的像素值。您的值完全低于该范围,因此是黑色图像;你需要改造它们。
获取彩色图像(而不是灰度图)需要模式='P',这需要您将数据转换为字节数组。
要使用颜色图绘制图像,我建议您使用 matplotlib.pyplot.imshow。
对您的 test.wav
文件执行此操作的结果如下所示:
有关使用 python 创建音频频谱图的更多详细信息,您可以阅读更多相关内容 here
根据答案here, you can use matplotlib colormaps 在转换为图像之前转换 numpy 数组。
#im = Image.fromarray(s+200, mode='F')
from matplotlib import cm
s = (s + 200)/200.0 # input data should range from 0-1
im = Image.fromarray(cm.jet(s, bytes=True))
im.show()
您可能应该根据您的 min/max 值适当地设置缩放比例。
示例输出: