Сохранение массива Numpy в виде изображения - PullRequest
213 голосов
/ 24 мая 2009

У меня есть матрица в виде массива Numpy. Как бы я записал его на диск как образ? Работает любой формат (png, jpeg, bmp ...). Одним из важных ограничений является то, что PIL отсутствует.

Ответы [ 18 ]

236 голосов
/ 11 ноября 2009

Используется 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')
160 голосов
/ 16 декабря 2011

Ответ с использованием PIL (на всякий случай, если он полезен).

с учетом массива «A»:

from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")

Вы можете заменить «jpeg» практически любым форматом, который вы хотите. Подробнее о форматах здесь

58 голосов
/ 03 апреля 2014

С 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.

enter image description here

55 голосов
/ 04 октября 2013

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)

50 голосов
/ 24 мая 2009

Вы можете использовать PyPNG . Это чистый Python (без зависимостей) кодировщик / декодер PNG с открытым исходным кодом, и он поддерживает запись массивов NumPy в виде изображений.

35 голосов
/ 25 ноября 2014

Для Python opencv (документация здесь ).

import cv2
import numpy as np

cv2.imwrite("filename.png", np.zeros((10,10)))

полезно, если вам нужно больше обрабатывать, чем сохранять.

30 голосов
/ 10 июня 2009

Если у вас есть matplotlib, вы можете сделать:

import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)

Это сохранит сюжет (не сами изображения). enter image description here

11 голосов
/ 11 марта 2018

Вы можете использовать библиотеку 'Skimage' в Python

Пример:

from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
11 голосов
/ 10 января 2014

Приложение к ответу @ 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:

Grid of red, yellow, dark-aqua, grey

(Прозрачность также работает, уменьшая старший байт с 0xff.)

6 голосов
/ 25 августа 2018

scipy.misc выдает предупреждение об устаревании функции imsave и предлагает вместо нее использовать imageio.

import imageio
imageio.imwrite('image_name.png', img)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...