有没有办法将pyplot.imshow()对象转换为numpy数组?
我需要把一个二维的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 个回答
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)
这样你会得到一个在 0
和 1
之间映射的 MxNx4 数组,
mapped_datau8 = (255 * my_cm(normed_data)).astype('uint8')
或者
mapped_data = my_cm(normed_data, bytes=True)
会把它转换成无符号整数。
matplotlib
提供了一系列的归一化代码,可以在这里查看。
编辑:修正了在 https://stackoverflow.com/a/14880947/380231 提到的遗漏。