Вопрос

У меня есть матрица типа массива 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')

Ответ с использованием ПИЛ (на всякий случай это полезно).

учитывая массив NumPy "A":

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

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

С 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

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)

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

import cv2
import numpy as np

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

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

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

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

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

Дополнение к ответу @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.)

Вы можете использовать библиотеку 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, который он создает:

example1.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, то нет ничего проще, чем просто щелкнуть правой кнопкой мыши массив в проводнике переменных и затем выбрать опцию «Показать изображение».

enter image description here

Вам будет предложено сохранить изображение в 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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top