Почему PIL и matplotlib создают здесь совершенно разные образы?

#python #matplotlib #python-imaging-library

#python #matplotlib #python-imaging-library

Вопрос:

Я создавал изображение чего-либо из массива, и matplotlib может выдавать только определенный «dpi» до сбоя ядра после того, как вы его зададите (например, для графика dpi = 8000 ядро просто мгновенно умирает). Поэтому я решил создать изображение с помощью PIL — но это было полностью испорчено.

Я создал MCVE:

 a = np.zeros([5,5])
a[:,2] = 255
a = np.repeat(a[...,np.newaxis], 3, axis=2)
 

Если мы matplotlib завершим это с

 img = plt.imshow(a)
plt.show()
 

Мы получаем это изображение:Чрезвычайно простой ожидаемый сюжет.

Но если мы используем аналогичный код PIL

 img = Image.fromarray(a, "RGB")
img.save("Stuff.png")
 

мы получаем это изображение:

Сумасшедшее изображение со странными цветами.

(Изображение здесь было снято с экрана и увеличено, потому что на самом деле оно составляет всего 5×5 пикселей)

Почему это так ?! Это просто ошибка ?!

РЕДАКТИРОВАТЬ: вопрос теперь решен, и благодаря этому и предыдущему вопросу мои вычисления намного быстрее и более pythonic. В качестве благодарности SO, вот скриншот 400-мегапиксельного изображения множества Мандельброта, окрашенного на основе квадранта C, в котором точка Z заканчивается так же, как она ускользает, что теперь может быть вычислено за 2 минуты:

введите описание изображения здесь

Комментарии:

1. PIL ожидает массив HxWxC, и вы просто передаете [5,5] . Можете ли вы попробовать сделать a = np.zeros([5,5,3]) вместо этого?

2. Я передаю массив HxWxC. Это то, что делает строка 3 при инициализации a, в противном случае PIL просто отклонит a .

3. мой плохой, я что-то пропустил на виду

Ответ №1:

Вы используете 64-разрядные значения с плавающей запятой в качестве входных данных, поскольку это тип dtype по умолчанию для np.zeros() . fromarray() режим «RGB» требует 3 x 8 бит пикселей.

Попробуйте с:

 img = Image.fromarray(a.astype(np.uint8), "RGB")