【问题标题】:Using colormap to create a PIL Image from the luminosity map of an image使用颜色图从图像的亮度图创建 PIL 图像
【发布时间】:2020-05-31 18:15:55
【问题描述】:

我有 M 个向量,其中包含 4096 个介于 0 和 1 之间的数据点,它们代表人脸的亮度图。这是实际图像的示例。

现在,我的目的是将它们放在一个有情节的视觉效果中,但为此我需要提供一个代表图像的 PIL 对象,这是我的 MVC

import PIL.Image as pilim
import matplotlib.cm as cm
import numpy as np

greys = cm.get_cmap('Greys')
num_images = 10
num_faces = faces.shape[0]
sample_images = np.random.choice(num_faces, num_images, replace=False)

for index in sample_images:
     greyscale = np.apply_along_axis(greys, 0, faces[index]).reshape((64, 64, 4))
     im = pilim.fromarray(greyscale, mode='RGBA')
     im.save('test{}.png'.format(index))    greys = cm.get_cmap('Greys')

Faces 是一个包含 698 个样本的 ndarray。类似于以下示例

[[0.01617647 0.01617647 0.01617647 ... 0.         0.         0.        ]
 [0.01617647 0.01617647 0.01617647 ... 0.         0.         0.        ]
 [0.01617647 0.01617647 0.01617647 ... 0.         0.         0.        ]]

这是我令人沮丧的结果

【问题讨论】:

    标签: python-3.x numpy matplotlib python-imaging-library


    【解决方案1】:

    PIL 使用像素数据,因此每个 RGBA 都是 0 到 255 之间的值。颜色图默认生成其 RGBA 值在 0-1 范围内。要转换它们,您可以将它们乘以 255 并转换为 8 位无符号整数 (uint8),如下所示:

    greyscale = np.uint8(cmap(faces[index].reshape(64,64)) * 255)
    

    但是,matplotlib 的颜色图也支持直接生成这些字节的参数:

    greyscale = cmap(faces[index].reshape(64,64), bytes=True)
    

    之后您可以将数组重新整形为 (64,64,4),但在应用颜色图之前进行转换更容易且更易读。

    对于此类图像,有多个sequential colormaps 可供选择。将_r 附加到名称后会提供反向颜色图(如此黑暗和浅色颠倒)。

    以下是一些帮助您入门的代码:

    import PIL.Image as pilim
    import matplotlib.cm as cm
    import numpy as np
    from matplotlib import pyplot as plt
    
    cmap = cm.get_cmap('copper_r') # 'bone_r', 'Greys', 'copper_r', 'Purple', ...
    num_images = 1
    
    faces = np.tile(np.linspace(0,1,4096), 698).reshape(698, 4096)
    
    num_faces = faces.shape[0]
    sample_images = np.random.choice(num_faces, num_images, replace=False)
    print(sample_images)
    for index in sample_images:
         greyscale = cmap(faces[index].reshape(64,64), bytes=True)
         im = pilim.fromarray(greyscale, mode='RGBA')
         im.save(f'test{index}.png')
    

    PS:matplotlib中还有一个imsave函数,可以进一步简化代码:

    for index in sample_images:
         plt.imsave(f'test{index}.png', faces[index].reshape(64,64), cmap=cmap)
    

    如果图像会颠倒显示,将origin='lower' 添加到imsave 会反转它。

    【讨论】:

      【解决方案2】:

      解决方案实际上非常简单。我的代码缺少两个步骤:

      1. 重新缩放到 0-255 个值
      2. 转换为 uint8 以便 PIL 理解数组

        灰度 = np.apply_along_axis(greys, 0, faces[index]).reshape((64, 64, 4))*255 灰度 = grayscale.astype(np.uint8) im = pilim.fromarray(灰度)

      https://python-decompiler.com/article/2012-06/how-to-convert-numpy-array-to-pil-image-applying-matplotlib-colormap

      【讨论】:

      • 或者只是greyscale = greys(faces[index].reshape(64,64), bytes=True)
      猜你喜欢
      • 1970-01-01
      • 2010-12-11
      • 2020-03-14
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多