为什么图像存储和显示不同?

时间:2017-05-13 09:12:45

标签: python numpy matplotlib librosa

我在保存我正在显示为numpy ndarays的图像时遇到一些问题。

示例:

此代码:

librosa.display.specshow(static.T,sr=16000,x_axis='frames',y_axis='mel',hop_length=160,cmap=cm.jet)
plt.title("log mel power spectrum of " + name)
plt.colorbar(format='%+02.0f dB')
plt.tight_layout()
plt.savefig(plot+"/"+name+"_plot_static_conv.png")
plt.show()

将显示如下图像:

enter image description here

但是当我将图像存储到一个numpy ndarray中,然后尝试绘制它时,我会得到类似的东西..

convert = plt.get_cmap(cm.jet)
numpy_output_static = convert(static.T)
plt.imshow(numpy_output_static)
plt.show()
raw_input("sadas")

给我看一张图片:

enter image description here

发生了什么?为什么我不能存储相同的图像,并以同样的方式查看它?

最小的工作示例:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from PIL import Image
import librosa
import librosa.display
from matplotlib import cm


fig = plt.figure(figsize=(12,4))
min = -1.828067
max = 22.70058
data =  np.random.uniform(low=min, high=max, size=(474,40))
librosa.display.specshow(data.T,sr=16000,x_axis='frames',y_axis='mel',hop_length=160,cmap=cm.jet)
plt.show()
raw_input("sadas")

convert = plt.get_cmap(cm.jet)
numpy_output_static = convert(data.T)
plt.imshow(numpy_output_static, aspect = 'auto')
plt.show()
raw_input("asds")

第一个情节是:

enter image description here

第二个情节是:

enter image description here

规范化数据集不会修复第二个图像。

1 个答案:

答案 0 :(得分:0)

您的问题与您使用imshow的方式有关(请参阅下面的说明)。

解决方案

我已将您的输入数据从随机内容转换为常规内容,以便比较更直接。我使用下面的实现得到了一个很好的匹配结果:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
import librosa
import librosa.display

data = np.linspace(-1.828067,22.70058,474*40).reshape(474,40)

fig = plt.figure(figsize=(12,8))

ax1 = fig.add_subplot(2,1,1)
librosa.display.specshow(data.T,sr=16000,x_axis='frames',y_axis='mel',hop_length=160,cmap=cm.jet)

ax2 = fig.add_subplot(2,1,2)
extent = (0,474,0,9325.7)
plt.imshow(data.T,cmap='jet',extent=extent)
ax2.set_aspect(abs((extent[1]-extent[0])/(extent[3]-extent[2]))/4.)

plt.show()

结果:

enter image description here

说明

现在,出了什么问题?你用过

convert = plt.get_cmap(cm.jet)

结果convert最好被视为包含 256 RGBA颜色条目的列表:

>>> convert(0)
(0.0, 0.0, 0.5, 1.0)

>>> convert(1)
(0.0, 0.0, 0.517825311942959, 1.0)

>>> convert(2)
(0.0, 0.0, 0.535650623885918, 1.0)

...

>>> convert(254)
(0.517825311942959, 0.0, 0.0, 1.0)

>>> convert(255)
(0.5, 0.0, 0.0, 1.0)

现在的诀窍是它是一个'特殊'列表,它只会在越界时返回最大值:

>>> convert(256)
(0.5, 0.0, 0.0, 1.0)

>>> convert(257)
(0.5, 0.0, 0.0, 1.0)

... 

>>> convert(1000)
(0.5, 0.0, 0.0, 1.0)

这正是发生在你身上的事。因此,你的图表几乎全是红色(“jet”的最后一种颜色)。

相反,在我提供的代码中,数据被映射到256种颜色(最小值被分配convert(0),最大值convert(255)或更一般地:(value-min_val)*255/(max_val-min_val)

参考