【问题标题】:Why is the image stored and show different?为什么图像存储和显示不同?
【发布时间】:2017-05-13 09:12:45
【问题描述】:

我在将显示的图像保存为 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()

将显示如下图像:

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

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

给我看一张图片:

这是怎么回事?.. 为什么我不能存储相同的图像,并以相同的方式查看它?

最小的工作示例:

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")

第一个情节是:

第二个情节是:

规范化数据集并不能修复第二张图像。

【问题讨论】:

  • 请尝试提出minimal working example。它很可能与颜色轴的限制有关......您可以添加一个颜色条来找出答案。见this answer
  • dB 也是对数轴。我们只能猜测static是哪个单位??????
  • 您能否修改您的帖子以使其可以被复制。 IE。生成静态,并相应地修改图像?另外,你研究过色阶吗?
  • 我目前正在使用真实数据制作一个示例..我尝试了随机值,它似乎可以正常工作..但在 static 数据集上它似乎搞砸了..
  • @TomdeGeus 我已经添加了示例。我尝试增加了限制。结果相同

标签: python numpy matplotlib librosa


【解决方案1】:

您的问题与您使用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()

结果:

说明

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

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)

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

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

参考

【讨论】:

  • 我不确定这里的答案是什么...?你是说我应该将随机数据转换为 0 - 255 的范围,然后对其进行 cmaps,然后当我绘制 cmaped 数据时,一切都应该没问题?
  • 我不确定这是否能解决问题?.. 我似乎无法在我的用例中复制您的结果。即使我对其进行规范化,我仍然会得到红色图像..除此之外..您所说的情况并非如此,因为最大值是 22 而不是高于 255.. 所以..
  • 我是说你应该让 matplotlib 做颜色映射,你不应该尝试手动做。因此,将原始数据与颜色图的名称以及可选的限制放在imshow 中,让它发挥它的魔力。这是我回答的第一部分。第二部分只是解释您的手动映射失败的原因。但再次让图书馆做它的事,这就是存在的地方。
  • 问题是存储为 numpy ndarray 的图像用作 nn 的输入,这意味着表示很重要......我需要将绘图存储为 numpy 数组,每个像素对应于图中的像素..
  • 现在我真的很困惑...您的输入是一个 numpy 数组和最准确的表示!?我们一直在谈论的是用颜色在视觉上忏悔,让我们人类用它做点什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
  • 2020-11-22
  • 2015-12-08
  • 2014-07-15
相关资源
最近更新 更多