У меня есть матрица в виде массива Numpy. Как бы я записал его на диск как образ? Работает любой формат (png, jpeg, bmp ...). Одним из важных ограничений является то, что PIL отсутствует.
Я просто хотел бы отметить, что некоторые из ответов ниже, и, конечно, некоторые из людей, которые приходят и находят этот вопрос, не соответствуют указанному выше ограничению - быть без PIL . Поскольку некоторые спрашивающие и некоторые ответы оба избегают этого ограничения, я призываю всех, кто здесь, и не возражает против того, чтобы PIL смотрел ниже, и любые не-PIL ответы (новые или старые), чтобы упомянуть, что они используются PIL. тип ответа, чтобы отличить себя от ответов, отвечающих первоначальному ограничению.
Вы можете использовать PyPNG . Это чистый Python (без зависимостей) открытый кодировщик / декодер PNG с открытым исходным кодом, и он поддерживает запись массивов NumPy в виде изображений.
Не забудьте масштабировать значения до нужного диапазона для PNG, обычно 0..255. Диапазоны значений в нейронных сетях часто равны 0..1 или -1..1.
Томаш Гавенчяк
8
PyPNG - это чистый Python, который уменьшает свои внешние зависимости, но делает его намного медленнее, чем PIL и его производные классы. Например, сохранение изображения 3000x4000 на моем компьютере заняло 4,05 секунды с PyPNG, но всего 0,59 секунды с scipy.misc.imsave (в 6 раз быстрее).
Звика
@ TomášGavenčiak - scipy.misc.imsave больше не поддерживается в новых версиях Scipy. Альтернативой нескольким комментариям ниже является использование imageio.imwrite ('image_file.jpg', array)
Пси-Эд
259
Это использует PIL, но, возможно, некоторые могут найти это полезным:
РЕДАКТИРОВАТЬ : текущая scipyверсия начала нормализовать все изображения так, чтобы min (данные) стали черными, а max (данные) стали белыми. Это нежелательно, если данные должны иметь точные уровни серого или точные каналы RGB. Решение:
imsave живет в ... / scipy / misc / pilutil.py, который использует PIL
Денис
5
Будьте осторожны при конвертации в jpg, так как это с потерями, и поэтому вы не сможете восстановить точные данные, использованные для генерации изображения.
Феанил
8
Это теперь устарело при использовании scipy 0.19 - scipy.io.imwrite
g.stevo
6
«imsave устарела в SciPy 1.0.0 и будет удалена в 1.2.0» ( Scipy 1.1.0 doc )
noobar
15
scipy.misc.imsave устарела. использовать импорт imageio; imageio.imwrite ('file_name.jpg', nmupy_array)
ChaosPredictor
228
Ответ с использованием PIL (на всякий случай, если это полезно).
учитывая массив N "n"
from PIL importImage
im =Image.fromarray(A)
im.save("your_file.jpeg")
Вы можете заменить «JPEG» практически любой формат, который вы хотите. Подробнее о форматах здесь
Изображение представляет собой модуль PIL. Сделайте «печать изображения .__ файл__»
Juh_
10
Очень полезно для тех из нас, кто бродил здесь и у кого есть PIL - я думаю, я буду использовать, from PIL import Imageчтобы держать это в чистоте ...
мудрец
4
Если у вас есть RGB-изображение, вы можете получить его с помощью im = Image.fromarray (A) .convert ('RGB'). Дополнительная информация: stackoverflow.com/questions/4711880/…
Roger Veciana
Использование третьей оси массива uint8 для кодирования RGB работает с этим методом. Модуль PIL может быть установлен с помощью «pip install pillow».
ло
1
@Ludovico Verniani Это не искажает изображения, но оно использует несколько необычную цветовую кодировку, в которой порядок цветов - BGR, а не RGB.
Работает с Matplotlib 1.3.1, я не знаю о более низкой версии. Из строки документации:
Arguments:*fname*:
A string containing a path to a filename,or a Python file-like object.If*format*is*None*and*fname*is a string, the output
format is deduced from the extension of the filename.*arr*:AnMxN(luminance),MxNx3(RGB)orMxNx4(RGBA) array.
@HughPerkins попробовать подушку в качестве замены PIL в Python 3
christianbrodbeck
10
import matplotlib.pyplot as pltа затемplt.imsave('name.png', array)
Алессандро Якопсон
62
Pure Python (2 и 3), фрагмент без сторонних зависимостей.
Эта функция записывает сжатые RGBAPNG- изображения истинного цвета (4 байта на пиксель) .
def write_png(buf, width, height):""" buf: must be bytes or a bytearray in Python3.x,
a regular string in Python2.x.
"""import zlib, struct
# reverse the vertical line order and add null bytes at the start
width_byte_4 = width *4
raw_data = b''.join(
b'\x00'+ buf[span:span + width_byte_4]for span in range((height -1)* width_byte_4,-1,- width_byte_4))def png_pack(png_tag, data):
chunk_head = png_tag + data
return(struct.pack("!I", len(data))+
chunk_head +
struct.pack("!I",0xFFFFFFFF& zlib.crc32(chunk_head)))return b''.join([
b'\x89PNG\r\n\x1a\n',
png_pack(b'IHDR', struct.pack("!2I5B", width, height,8,6,0,0,0)),
png_pack(b'IDAT', zlib.compress(raw_data,9)),
png_pack(b'IEND', b'')])
... Данные должны быть записаны непосредственно в файл, открытый в двоичном виде, как в:
data = write_png(buf,64,64)with open("my_image.png",'wb')as fh:
fh.write(data)
Кажется, это именно то, что я ищу, но не могли бы вы добавить несколько комментариев? Я не вижу, как это пишет в файл. Нужно ли записывать вывод в ранее открытый файл? Спасибо!
PhilMacKay
1
@PhilMacKay, данные просто должны быть записаны в двоичный файл. добавлен комментарий.
ideasman42
1
Кто-то может указать, в каком формате bufдолжно быть изображение ( )? Похоже, это не просто массив ...
Нет, для интерфейса pyplot plt.figure () является излишним. Кроме того, вам нужен только plt.show (), если вы хотите увидеть также окно с рисунком - в этом случае требуется только сохранение файла изображения, поэтому нет необходимости вызывать show ().
DopplerShift
7
Обратите внимание, что полученный файл изображения будет содержать оси и серую область рисунка matlplotlib, а не только данные пикселей.
Дэйв
1
не будет работать, если вы запустите свой скрипт на удаленном хосте, подключившись к нему без поддержки графического интерфейса.
Темак
Если вы хотите показать изображение в блокноте, вы можете добавить следующее: >> «из IPython.display import Image», а затем >> «Image (filename = filename)»
Robert
Чтобы снять ось:plt.axis('off')
yakout
15
Вы можете использовать библиотеку 'Skimage' в Python
Пример:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
def saveAsPNG(array, filename):import struct
if any([len(row)!= len(array[0])for row in array]):raiseValueError,"Array should have elements of equal size"#First row becomes top row of image.
flat =[]; map(flat.extend, reversed(array))#Big-endian, unsigned 32-byte integer.
buf = b''.join([struct.pack('>I',((0xffFFff& i32)<<8)|(i32>>24))for i32 in flat])#Rotate from ARGB to RGBA.
data = write_png(buf, len(array[0]), len(array))
f = open(filename,'wb')
f.write(data)
f.close()
Для тех, кто ищет прямой полностью рабочий пример:
from PIL importImageimport numpy
w,h =200,100
img = numpy.zeros((h,w,3),dtype=numpy.uint8)# has to be unsigned bytes
img[:]=(0,0,255)# fill blue
x,y =40,20
img[y:y+30, x:x+50]=(255,0,0)# 50x30 red boxImage.fromarray(img).convert("RGB").save("art.png")# don't need to convert
Кроме того, если вы хотите высокое качество JPEG .save(file, subsampling=0, quality=100)
Matplotlib SVN имеет новую функцию для сохранения изображений в виде просто изображения - без осей и т. д. Это очень простая функция для бэкпорта тоже, если вы не хотите устанавливать SVN (скопировано прямо из image.py в Matplotlib SVN, удалил документация для краткости):
Мир, вероятно, не нуждается в еще одном пакете для записи массива в PNG-файл, но для тех, кто не может получить достаточно, я недавно выложил numpngw github:
Вот первый пример из examplesкаталога репозитория. Основная линия просто
write_png('example1.png', img)
где imgмассив NumPy. Весь код перед этой строкой - операторы импорта и код для создания img.
import numpy as np
from numpngw import write_png
# Example 1## Create an 8-bit RGB image.
img = np.zeros((80,128,3), dtype=np.uint8)
grad = np.linspace(0,255, img.shape[1])
img[:16,:,:]=127
img[16:32,:,0]= grad
img[32:48,:,1]= grad[::-1]
img[48:64,:,2]= grad
img[64:,:,:]=127
write_png('example1.png', img)
Мне любопытно, чем ваша библиотека отличается от других? Это быстрее? У этого есть причудливые особенности?
Ф Лекшас
Несколько особенностей: (1) Он использует массивы NumPy. (2) Он написан с использованием только python и numpy, поэтому он не требует установки библиотеки C. (3) Он может создавать анимированные файлы PNG. (4) Он предоставляет класс для написания анимаций matplotlib в виде анимированных файлов PNG.
Уоррен Векессер
Спасибо! Мне было бы любопытно, как это сравнивается с stackoverflow.com/a/19174800/981933 с точки зрения производительности, которая также является чистым Python. Первый метод выше в 2 раза быстрее, чем PIL, что довольно круто. Не
бери в голову,
2
Предполагая, что вы хотите изображение в градациях серого:
im =Image.new('L',(width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
ImageIO - это библиотека Python, которая предоставляет простой интерфейс для чтения и записи широкого спектра данных изображений, включая анимированные изображения, видео, объемные данные и научные форматы. Он кроссплатформенный, работает на Python 2.7 и 3.4+ и прост в установке.
Это пример для изображения в градациях серого:
import numpy as np
import imageio
# data is numpy array with grayscale value for each pixel.
data = np.array([70,80,82,72,58,58,60,63,54,58,60,48,89,115,121,119])# 16 pixels can be converted into square of 4x4 or 2x8 or 8x2
data = data.reshape((4,4)).astype('uint8')# save image
imageio.imwrite('pic.jpg', data)
Если вы уже используете [Py] Qt, вас может заинтересовать qimage2ndarray . Начиная с версии 1.4 (только что выпущенной), PySide также поддерживается, и будет небольшая imsave(filename, array)функция, похожая на scipy, но использующая Qt вместо PIL. С 1.3 просто используйте что-то вроде следующего:
qImage = array2qimage(image, normalize =False)# create QImage from ndarray
success = qImage.save(filename)# use Qt's image IO functions for saving PNG/JPG/..
(Еще одним преимуществом 1.4 является то, что это чисто Python-решение, что делает его еще более легким.)
Выпуск 1.4 уже вышел. :-) (Я соответственно отредактировал ответ.)
hans_meine
1
Если вы работаете в среде Python Spyder, то это не может быть проще, чем просто щелкнуть правой кнопкой мыши массив в проводнике переменных, а затем выбрать параметр Показать изображение.
Это попросит вас сохранить изображение в dsik, в основном в формате PNG.
import cv2
assert mat.shape[2]==1or mat.shape[2]==3,'the third dim should be channel'
cv2.imwrite(path, mat)# note the form of data should be height - width - channel
Ответы:
Вы можете использовать PyPNG . Это чистый Python (без зависимостей) открытый кодировщик / декодер PNG с открытым исходным кодом, и он поддерживает запись массивов NumPy в виде изображений.
источник
Это использует PIL, но, возможно, некоторые могут найти это полезным:
РЕДАКТИРОВАТЬ : текущая
scipy
версия начала нормализовать все изображения так, чтобы min (данные) стали черными, а max (данные) стали белыми. Это нежелательно, если данные должны иметь точные уровни серого или точные каналы RGB. Решение:источник
Ответ с использованием PIL (на всякий случай, если это полезно).
учитывая массив N "n"
Вы можете заменить «JPEG» практически любой формат, который вы хотите. Подробнее о форматах здесь
источник
from PIL import Image
чтобы держать это в чистоте ...С
matplotlib
:Работает с Matplotlib 1.3.1, я не знаю о более низкой версии. Из строки документации:
источник
matplotlib.pyplot.imsave
в матплотлибе 2+import matplotlib.pyplot as plt
а затемplt.imsave('name.png', array)
Pure Python (2 и 3), фрагмент без сторонних зависимостей.
Эта функция записывает сжатые
RGBA
PNG- изображения истинного цвета (4 байта на пиксель) .... Данные должны быть записаны непосредственно в файл, открытый в двоичном виде, как в:
источник
buf
должно быть изображение ( )? Похоже, это не просто массив ...Есть
opencv
для Python ( документация здесь ).полезно, если вам нужно больше обрабатывать, чем сохранять.
источник
np.zeros((10,10))
своим изображением.cmap="gray"
когда я сохраняю изображение с помощью cv2?Если у вас есть matplotlib, вы можете сделать:
Это сохранит сюжет (не сами изображения).
источник
plt.axis('off')
Вы можете использовать библиотеку 'Skimage' в Python
Пример:
источник
scipy.misc
выдает предупреждение об устареванииimsave
функции и предлагает использоватьimageio
вместо этого.источник
Приложение к ответу @ ideasman42:
Так что вы можете сделать:
Производство
test_grid.png
:(Прозрачность также работает, уменьшая старший байт от
0xff
.)источник
Для тех, кто ищет прямой полностью рабочий пример:
Кроме того, если вы хотите высокое качество JPEG
.save(file, subsampling=0, quality=100)
источник
Matplotlib SVN имеет новую функцию для сохранения изображений в виде просто изображения - без осей и т. д. Это очень простая функция для бэкпорта тоже, если вы не хотите устанавливать SVN (скопировано прямо из image.py в Matplotlib SVN, удалил документация для краткости):
источник
Мир, вероятно, не нуждается в еще одном пакете для записи массива в PNG-файл, но для тех, кто не может получить достаточно, я недавно выложил
numpngw
github:https://github.com/WarrenWeckesser/numpngw
и по пипи: https://pypi.python.org/pypi/numpngw/
Единственная внешняя зависимость - тупая.
Вот первый пример из
examples
каталога репозитория. Основная линия простогде
img
массив NumPy. Весь код перед этой строкой - операторы импорта и код для созданияimg
.Вот файл PNG, который он создает:
источник
Предполагая, что вы хотите изображение в градациях серого:
источник
ImageIO - это библиотека Python, которая предоставляет простой интерфейс для чтения и записи широкого спектра данных изображений, включая анимированные изображения, видео, объемные данные и научные форматы. Он кроссплатформенный, работает на Python 2.7 и 3.4+ и прост в установке.
Это пример для изображения в градациях серого:
источник
Если вы уже используете [Py] Qt, вас может заинтересовать qimage2ndarray . Начиная с версии 1.4 (только что выпущенной), PySide также поддерживается, и будет небольшая
imsave(filename, array)
функция, похожая на scipy, но использующая Qt вместо PIL. С 1.3 просто используйте что-то вроде следующего:(Еще одним преимуществом 1.4 является то, что это чисто Python-решение, что делает его еще более легким.)
источник
Если вы работаете в среде Python Spyder, то это не может быть проще, чем просто щелкнуть правой кнопкой мыши массив в проводнике переменных, а затем выбрать параметр Показать изображение.
Это попросит вас сохранить изображение в dsik, в основном в формате PNG.
Библиотека PIL в этом случае не понадобится.
источник
Использование
cv2.imwrite
.источник
для сохранения массива в виде изображения у вас есть несколько вариантов:
1) лучший из других: OpenCV
2) Матплотлиб
3) ПИЛ
4) ...
источник