Использование карты цветов для создания изображения PIL из карты яркости изображения - PullRequest
0 голосов
/ 16 февраля 2020

У меня есть M векторов, содержащих 4096 точек данных от 0 до 1, которые представляют карту яркости граней. Это образец реальных изображений.

enter image description here

Теперь моя цель - представить их наглядно, но для этого мне нужно предоставить объект 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')

Лица - это ndarray с 698 образцами. Что-то вроде следующего образца

[[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.        ]]

, и это мой удручающий результат

enter image description here

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

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 приведет к его обращению.

0 голосов
/ 17 февраля 2020

Решение на самом деле довольно простое. В моем коде пропущено два шага:

  1. масштабирование до значений 0-255
  2. Приведение к uint8, чтобы PIL мог понять массив

    greyscale = np.apply_along_axis (серые, 0, грани [index]). Reshape ((64, 64, 4)) * 255 greyscale = greyscale.astype (np.uint8) im = pilim.fromarray (greyscale)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...