Сохранение массива Numpy как изображения
Вопрос
У меня есть матрица типа массива Numpy.Как мне записать его на диск как образ?Подойдет любой формат (png, jpeg, bmp...).Одним из важных ограничений является отсутствие PIL.
Решение
Вы можете использовать ПиПНГ.Это чистый кодировщик/декодер PNG Python (без зависимостей) с открытым исходным кодом, и он поддерживает запись массивов NumPy в виде изображений.
Другие советы
Здесь используется PIL, но, возможно, кому-то это может оказаться полезным:
import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)
РЕДАКТИРОВАТЬ:Электрический ток scipy
версия начала нормализовать все изображения так, что min(данные) стали черными, а max(данные) стали белыми.Это нежелательно, если данные должны иметь точные уровни серого или точные каналы RGB.Решение:
import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
С matplotlib
:
import matplotlib
matplotlib.image.imsave('name.png', array)
Работает с 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*:
An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array.
Pure Python (2 и 3), фрагмент без сторонних зависимостей.
Эта функция записывает сжатые истинные цвета (4 байта на пиксель). RGBA
PNG.
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 fd:
fd.write(data)
- Первоисточник
- Смотрите также: Rust Port из этого вопроса.
- Пример использования благодаря @Evgeni Sergeev: https://stackoverflow.com/a/21034111/432509
Есть opencv
для питона (документация здесь).
import cv2
import numpy as np
cv2.imwrite("filename.png", np.zeros((10,10)))
полезно, если вам нужно выполнить дополнительную обработку, кроме сохранения.
Дополнение к ответу @ideasman42:
def saveAsPNG(array, filename):
import struct
if any([len(row) != len(array[0]) for row in array]):
raise ValueError, "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()
Итак, вы можете сделать:
saveAsPNG([[0xffFF0000, 0xffFFFF00],
[0xff00aa77, 0xff333333]], 'test_grid.png')
Производство test_grid.png
:
(Прозрачность также работает, уменьшая старший байт от 0xff
.)
Вы можете использовать библиотеку Skimage в Python.
Пример:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
scipy.misc
выдает предупреждение об устаревании imsave
функцию и предлагает использовать imageio
вместо.
import imageio
imageio.imwrite('image_name.png', img)
В matplotlib svn появилась новая функция для сохранения изображений как просто изображений — без осей и т. д.это также очень простая функция для резервного копирования, если вы не хотите устанавливать svn (скопировано прямо из image.py в matplotlib svn, для краткости удалена строка документации):
def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, origin=None):
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False)
canvas = FigureCanvas(fig)
fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin)
fig.savefig(fname, dpi=1, format=format)
Для тех, кто ищет прямой полностью рабочий пример:
from PIL import Image
import 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 box
Image.fromarray(img).convert("RGB").save("art.png") # don't need to convert
также, если вам нужны файлы JPEG высокого качества
.save(file, subsampling=0, quality=100)
Миру, вероятно, не нужен еще один пакет для записи массива в PNG-файл, но для тех, кому этого недостаточно, я недавно выложил numpngw
на гитхабе:
https://github.com/WarrenWeckesser/numpngw
и на пипи: https://pypi.python.org/pypi/numpngw/
Единственная внешняя зависимость — numpy.
Вот первый пример из examples
каталог репозитория.Основная линия просто
write_png('example1.png', img)
где img
представляет собой пустой массив.Весь код перед этой строкой — это операторы импорта и код для создания 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)
Вот файл PNG, который он создает:
Предполагая, что вам нужно изображение в оттенках серого:
im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Если вы уже используете [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, что делает его еще более легким.)
Использовать cv2.imwrite
.
import cv2
assert mat.shape[2] == 1 or mat.shape[2] == 3, 'the third dim should be channel'
cv2.imwrite(path, mat) # note the form of data should be height - width - channel
Если вы работаете в среде Python Spyder, то нет ничего проще, чем просто щелкнуть правой кнопкой мыши массив в проводнике переменных и затем выбрать опцию «Показать изображение».
Вам будет предложено сохранить изображение в dsik, в основном в формате PNG.
Библиотека PIL в этом случае не понадобится.
Изображениеio — это библиотека 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)