如何使用matplotlib颜色图将NumPy数组转换为PIL图像


132

我有一个简单的问题,但找不到很好的解决方案。

我想获取一个代表灰度图像的NumPy 2D数组,并在应用一些matplotlib颜色图时将其转换为RGB PIL图像。

我可以使用以下pyplot.figure.figimage命令获得合理的PNG输出:

dpi = 100.0
w, h = myarray.shape[1]/dpi, myarray.shape[0]/dpi
fig = plt.figure(figsize=(w,h), dpi=dpi)
fig.figimage(sub, cmap=cm.gist_earth)
plt.savefig('out.png')

尽管我可以修改它以获取所需的东西(可能使用StringIO可以获取PIL图像),但我想知道是否没有一种更简单的方法可以这样做,因为这似乎是图像可视化的一个非常自然的问题。假设是这样的:

colored_PIL_image = magic_function(array, cmap)

对于完全正常工作的代码,您可能会参考:是否有任何好的彩色图使用python的PIL将灰度图像转换为彩色图像?
亚当

Answers:


220

一个班轮很忙,但是这里是:

  1. 首先,请确保您的NumPy数组myarray使用处的最大值进行了规范化1.0
  2. 将颜色表直接应用于myarray
  3. 重新调整0-255范围。
  4. 使用转换为整数np.uint8()
  5. 使用Image.fromarray()

这样就完成了:

from PIL import Image
from matplotlib import cm
im = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255))

plt.savefig()

在此处输入图片说明

im.save()

在此处输入图片说明


7
将“直接将颜色贴图应用于myarray”部分切入心脏!我不知道有可能,谢谢!
heltonbiker

34
研究了有关LinearSegmentedColormap的文档(cm.gist_earth是实例),我发现可以用“字节”参数调用它,该参数已经将其转换为uint8。然后,im = Image.fromarray(cm.gist_earth(myarray, bytes=True))
单线飞机

1
@CiprianTomoiaga,数组的形状应该是您想要的图像尺寸。例如,将从具有形状(1024,768)的阵列生成VGA图像。您应该注意到这适用于单色图像。这很重要,因为通常在将RGB图像转换为数组时,其形状为(1024,768,3),因为它具有三个通道。
heltonbiker '17

5
我遇到错误NameError: name 'cm' is not defined
rnso '18

10
@msofrom matplotlib import cm
Quantum7 '18

10
  • 输入= numpy_image
  • np.unit8->转换为整数
  • convert('RGB')->转换为RGB
  • Image.fromarray->返回图像对象

    from PIL import Image
    import numpy as np
    
    PIL_image = Image.fromarray(np.uint8(numpy_image)).convert('RGB')
    
    PIL_image = Image.fromarray(numpy_image.astype('uint8'), 'RGB')

5
希望它可以解决问题,但请在其中添加代码说明,以便用户完全理解他/她真正想要的。
Jaimil Patel

1
好,更新的答案。以前的是几年前的。
Catalina Chircu

7

即使应用了注释中提到的更改,接受的答案中描述的方法对我也不起作用。但是下面的简单代码有效:

import matplotlib.pyplot as plt
plt.imsave(filename, np_array, cmap='Greys')

np_array可以是2D数组,其值从0..1浮点型到o2 0..255 uint8,在这种情况下,它需要cmap。对于3D阵列,cmap将被忽略。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.