#python-3.x #numpy #python-imaging-library
#python-3.x #numpy #python-imaging-library
Вопрос:
У меня есть MxN ndarray, который содержит значения True и False внутри этих массивов, и я хочу нарисовать их в виде изображения. Цель состоит в том, чтобы преобразовать массив в изображение подушки с каждым истинным значением в качестве постоянного цвета. Я смог заставить его работать, прокручивая каждый пиксель и изменяя их по отдельности путем сравнения и рисования пикселя на пустом изображении, но этот метод слишком медленный.
# img is a PIL image result
# image is the MxN ndarray
pix = img.load()
for x in range(image.shape[0]):
for y in range(image.shape[1]):
if image[x, y]:
pix[y, x] = (255, 0, 0)
Есть ли способ изменить ndarray на MxNx3, заменив кортежи непосредственно на истинные значения?
Ответ №1:
Например, если у вас есть свой 2D-массив True / False и метка для цвета [255,255,255]
, будет работать следующее:
colored = np.expand_dims(bool_array_2d,axis=-1)*np.array([255,255,255])
Чтобы проиллюстрировать это на фиктивном примере: в следующем коде я создал случайную матрицу из 0 и 1, а затем превратил 1 в белый ([255,255,255]).
import numpy as np
import matplotlib.pyplot as plt
array = np.random.randint(0,2, (100,100))
colors = np.array([255,255,255])
colored = np.expand_dims(array, axis=-1)*colors
plt.imshow(colored)
Надеюсь, это помогло
Комментарии:
1. Отличная работа! Возможно , вы захотите добавить
.astype(np.uint8)
в конец, иначе это может выглядеть какint64
и занимать в ОЗУ в 8 раз больше места, и PIL / Pillow не сможет сохранить его, например, в формате PNG. Хотя у вас уже есть мой голос 🙂2. Большое вам спасибо. Да, я согласен с вами, в ситуации с интенсивными вычислениями или ограниченными возможностями приведение к uint_8 было бы абсолютно необходимо
3. Спасибо, это решение определенно то, к чему я стремился. Я нашел другое решение с преобразованием в изображение и обратным преобразованием, но это работает гораздо более универсально для массивов numpy.
Ответ №2:
Нашел другое решение, сначала преобразовал в изображение, затем преобразовал в RGB, затем преобразовал обратно в отдельный на 3 канала. Когда я пытался объединить несколько логических массивов вместе, этот способ был намного быстрее.
img = Image.fromarray(image * 1, 'L').convert('RGB')
data = np.array(img)
red, green, blue = data.T
area = (red == 1)
data[...][area.T] = (255, 255, 255)
img = Image.fromarray(data)
Ответ №3:
Я думаю, вы можете сделать это довольно просто и быстро, вот так:
# Make a 2 row by 3 column image of True/False values
im = np.random.choice((True,False),(2,3))
Мой выглядит так:
array([[False, False, True],
[ True, True, True]])
Теперь добавьте новую ось, сделайте ее 3-канальной и умножьте значения истинности на ваш новый «цвет»:
result = im[..., np.newaxis]*[255,255,255]
что дает вам это:
array([[[ 0, 0, 0],
[ 0, 0, 0],
[255, 255, 255]],
[[255, 255, 255],
[255, 255, 255],
[255, 255, 255]]])