У меня есть матрица в типе массива Numpy. Как записать его на диск как образ? Работает любой формат (png, jpeg, bmp...). Одним из важных ограничений является то, что PIL отсутствует.
Сохранение массива Numpy в качестве изображения
Ответ 1
Вы можете использовать PyPNG. Это чистый Python (без зависимостей) open source PNG encoder/decoder и поддерживает запись массивов NumPy в виде изображений.
Ответ 2
В этом случае используется PIL, но, возможно, некоторые из них могут оказаться полезными:
import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)
  EDIT. Текущая версия scipy начала нормализовать все изображения, чтобы мин (данные) стали черными, а макс (данные) стали белыми. Это нежелательно, если данные должны быть точными уровнями серого или точными каналами RGB. Решение:
import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
Ответ 3
Ответ с использованием PIL (на всякий случай это полезно).
для массива numpy "A":
from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")
вы можете заменить "jpeg" практически любым желаемым форматом. Подробнее о форматах здесь
Ответ 4
Pure Python (2 и 3), фрагмент без сторонних зависимостей.
 Эта функция записывает сжатые PNG- RGBA формате true color (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 fd:
    fd.write(data)
- Первоначальный источник
- Смотрите также: Rust Port из этого вопроса.
- Пример использования благодаря Евгению Сергееву: fooobar.com/questions/46126/...
Ответ 5
С matplotlib:
import matplotlib
matplotlib.image.imsave('name.png', array)
Работает с matplotlib 1.3.1, я не знаю о более низкой версии. Из документа docstring:
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.
Ответ 6
Если у вас есть matplotlib, вы можете сделать:
import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)
Ответ 7
Там opencv для python (http://docs.opencv.org/trunk/doc/py_tutorials/py_tutorials.html).
import cv2
import numpy as np
cv2.imwrite("filename.png", np.zeros((10,10)))
полезно, если вам нужно сделать больше обработки, кроме сохранения.
Ответ 8
Добавление к ответу @ideaman42:
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.)
Ответ 9
Вы можете использовать библиотеку 'Skimage' в Python
Пример:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
Ответ 10
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)
Ответ 11
 scipy.misc выдает предупреждение об imsave функции imsave и предлагает вместо этого использовать imageio.
import imageio
imageio.imwrite('image_name.png', img)
Ответ 12
В мире, вероятно, не нужен еще один пакет для записи массива numpy в PNG файл, но для тех, кто не может получить достаточно, я недавно положил numpngw на github:
https://github.com/WarrenWeckesser/numpngw
и на pypi: https://pypi.python.org/pypi/numpngw/
Единственная внешняя зависимость - numpy.
Вот первый пример из каталога 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)
Вот файл PNG, который он создает:
Ответ 13
Предполагая, что вам требуется изображение в оттенках серого:
im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Ответ 14
Если вы уже используете [Py] Qt, вас может заинтересовать qimage2ndarray. Начиная с версии 1.4 (только что выпущенной) поддерживается PySide, и будет крошечная функция imsave(filename, array), похожая на scipy's, но используя Qt вместо PIL. С 1.3 просто используйте что-то вроде следующего:
qImage = array2qimage(image, normalize = False) # create QImage from ndarray
success = qImage.save(filename) # use Qt image IO functions for saving PNG/JPG/..
(Еще одно преимущество 1.4 заключается в том, что это чистое решение python, что делает его еще более легким.)
Ответ 15
Для тех, кто ищет прямой полностью рабочий пример:
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)
Ответ 16
Если вы работаете в среде Python Spyder, то это не может быть проще, чем просто щелкнуть правой кнопкой мыши массив в проводнике переменных, а затем выбрать параметр Показать изображение.
Это попросит вас сохранить изображение в dsik, в основном в формате PNG.
Библиотека PIL в этом случае не понадобится.
Ответ 17
 Используйте 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  
Ответ 18
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)




