有没有办法将pyplot.imshow()对象转换为numpy数组?

8 投票
4 回答
16301 浏览
提问于 2025-04-17 15:51

我需要把一个二维的numpy数组可视化。我正在用pyplot来实现这个。

这是我的代码:

import cv2 as cv
import numpy as np
from matplotlib import pyplot

img = pyplot.imshow( radiance_val )
#radiance_val is a 2D numpy array of size = ( 512, 512 ) 
#filled with np.float32 values

pyplot.show()

我得到了预期的输出。

现在我想问的是,有没有办法把上面代码中的“img”从pyplot类型转换成numpy类型?我需要这样做是为了能把可视化的结果加载为opencv图像,然后进行进一步处理。我使用的是python 2.7,32位。


编辑 1: 在Thorsten Kranz的解决方案之后

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
import PIL
from cStringIO import StringIO

frame1 = plt.gca()
frame1.axes.get_xaxis().set_visible(False)
frame1.axes.get_yaxis().set_visible(False)
plt.imshow(np.random.random((10,10)))

buffer_ = StringIO()
plt.savefig( buffer_, format = "png", bbox_inches = 'tight', pad_inches = 0 )
buffer_.seek(0)

image = PIL.Image.open( buffer_ )

ar = np.asarray(image)
cv.imshow( 'a', ar )
cv.waitKey(0)
cv.destroyAllWindows()

在程序结束后,我收到了来自MS VC++运行库的运行时错误。我的猜测是因为打开了“buffer_”。不过我得到了需要的输出。


编辑 2: 通过以下方式关闭缓冲区

buffer_.close()

并没有解决运行时错误。

4 个回答

1

在这里,我找到了一种更简单的方法来把数组转换成rgba格式。我想把声谱图转换成使用magma颜色映射的rgb图像,下面是我做的事情;

import matplotlib.cm as cm
sm = cm.ScalarMappable(cmap='magma')
sm.set_clim(spect.min(), spect.max())
im = sm.to_rgba(spect)

plt.imshow(im)
plt.title(im.shape)

enter image description here

5

你确定要转换方法的返回值,还是整个图形呢?

如果是后者,你可以试试以下步骤:

  • 使用 savefig 将图形保存到一个 StringIO 缓冲区的图片中
  • 用 PIL 或 opencv 从这个缓冲区加载图片
  • 把它转换成一个 numpy 数组

下面是一个示例:

import numpy as np
import matplotlib.pyplot as plt
import PIL
from cStringIO import StringIO

plt.imshow(np.random.random((20,20)))
buffer_ = StringIO()
plt.savefig(buffer_, format = "png")
buffer_.seek(0)
image = PIL.Image.open(buffer_)
ar = np.asarray(image)
buffer_.close()

可以查看 savefig*args**kwargs,了解更多选项,比如 dpi(分辨率)、背景颜色、透明度、边距等等。

如果你只想要一个带颜色编码的图像,而不需要坐标轴、标签等,我还是会用同样的方法,只需使用

plt.subplots_adjust(0,0,1,1)

来让坐标轴覆盖整个图形。注意你的图形的 aspect(比例),否则 mpl 可能会再次缩小你的坐标轴。

12

除非你真的需要标记的刻度和其他东西,

im._rgba_cache

这样可以直接访问一个 MxNx4 的 numpy 数组,这个数组就是颜色映射的数据。

如果你只想要颜色映射的数据,其实可以完全不使用 imshow,而是自己直接对数据进行颜色映射(可以参考这个指南来选择你的颜色映射)。

my_cm = maplotlib.cm.get_cmap('Reds')
normed_data = (data - np.min(data)) / (np.max(data) - np.min(data))
mapped_data = my_cm(normed_data)

这样你会得到一个在 01 之间映射的 MxNx4 数组,

mapped_datau8 = (255 * my_cm(normed_data)).astype('uint8')

或者

mapped_data = my_cm(normed_data, bytes=True)

会把它转换成无符号整数。

matplotlib 提供了一系列的归一化代码,可以在这里查看

get_cmap 文档颜色映射图库

编辑:修正了在 https://stackoverflow.com/a/14880947/380231 提到的遗漏。

撰写回答