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), но преобразование проще и удобнее читать перед применением карты цветов.
Существует несколько вариантов последовательные цветовые карты для изображений этого типа. Добавление _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: Существует также imsave
функция в matplotlib, которая еще больше упростит код:
for index in sample_images:
plt.imsave(f'test{index}.png', faces[index].reshape(64,64), cmap=cmap)
Если изображение будет отображаться вверх ногами, добавление origin='lower'
к imsave
приведет к его обращению.