it-swarm.com.de

Speichern eines Numpy-Arrays als Bild

Ich habe eine Matrix in der Art eines Numpy-Arrays. Wie würde ich es als Image auf die Festplatte schreiben? Jedes Format funktioniert (png, jpeg, bmp ...). Eine wichtige Einschränkung ist, dass PIL nicht vorhanden ist.

192
M456

Sie können PyPNG verwenden. Es ist ein reiner Python-Open-Source-PNG-Encoder/Decoder (keine Abhängigkeiten) und unterstützt das Schreiben von NumPy-Arrays als Bilder.

44
dF.

Dies verwendet PIL, aber vielleicht finden es einige nützlich:

import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)

EDIT: Die aktuelle scipy-Version begann alle Bilder zu normalisieren, so dass min (Daten) schwarz und max (Daten) weiß werden. Dies ist unerwünscht, wenn die Daten genaue Graustufen oder exakte RGB-Kanäle haben sollen. Die Lösung:

import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
220
Steve Tjoa

Eine Antwort mit PIL (falls es nützlich ist).

ein numpy-Array "A" gegeben:

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

sie können "jpeg" durch fast jedes gewünschte Format ersetzen. Weitere Details zu den Formaten hier

138
migas

Mit matplotlib:

import matplotlib

matplotlib.image.imsave('name.png', array)

Funktioniert mit matplotlib 1.3.1, ich weiß nicht, welche Version niedriger ist. Aus dem 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.

 enter image description here

51

Pure Python (2 & 3), ein Snippet ohne Abhängigkeiten von Drittanbietern.

Diese Funktion schreibt komprimierte True-Color (4 Bytes pro Pixel) RGBA PNGs.

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'')])

... Die Daten sollten direkt in eine Datei geschrieben werden, die als Binärdatei geöffnet ist, wie in:

data = write_png(buf, 64, 64)
with open("my_image.png", 'wb') as fd:
    fd.write(data)

51
ideasman42

Es gibt opencv für Python ( Dokumentation hier ).

import cv2
import numpy as np

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

dies ist nützlich, wenn Sie außer dem Speichern mehr Verarbeitung durchführen möchten.

28
Xocoatzin

Wenn Sie Matplotlib haben, können Sie Folgendes tun:

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

Dadurch wird der Plot gespeichert (nicht die Bilder selbst).  enter image description here

27
DopplerShift

Nachtrag zu @ ideasman42's Antwort:

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()

So können Sie tun:

saveAsPNG([[0xffFF0000, 0xffFFFF00],
           [0xff00aa77, 0xff333333]], 'test_grid.png')

test_grid.png produzieren:

Grid of red, yellow, dark-aqua, grey

(Transparenz funktioniert auch, indem das High-Byte von 0xff reduziert wird.)

11
Evgeni Sergeev

Sie können die Skimage-Bibliothek in Python verwenden

Beispiel:

from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
9
PURNENDU MISHRA

scipy.misc gibt eine Warnung über imsave ab und schlägt stattdessen die Verwendung von imageio vor.

import imageio
imageio.imwrite('image_name.png', img)
4
Sefa

matplotlib svn hat eine neue Funktion, um Bilder nur als Bild zu speichern - keine Achsen usw. Es ist eine sehr einfache Funktion zum Zurückportieren, wenn Sie svn nicht installieren möchten (direkt aus image.py in matplotlib svn kopiert, entfernt docstring für die Kürze):

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)
4
Autoplectic

Für diejenigen, die ein direktes, voll funktionsfähiges Beispiel suchen:

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

auch, wenn Sie hochwertige JPEGs wollen
.save(file, subsampling=0, quality=100)

4
Puddle

Angenommen, Sie möchten ein Graustufenbild:

im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
2

Die Welt braucht wahrscheinlich kein weiteres Paket, um ein numpy-Array in eine PNG-Datei zu schreiben, aber für diejenigen, die nicht genug bekommen können, habe ich kürzlich numpngw auf github gestellt:

https://github.com/WarrenWeckesser/numpngw

und auf pypi: https://pypi.python.org/pypi/numpngw/

Die einzige externe Abhängigkeit ist numpy.

Hier ist das erste Beispiel aus dem Verzeichnis examples des Repositorys. Die wesentliche Linie ist einfach

write_png('example1.png', img)

dabei ist img ein numpy-Array. Der gesamte Code vor dieser Zeile besteht aus Importanweisungen und Code zum Erstellen von 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)

Hier ist die PNG-Datei, die erstellt wird:

 example1.png

2

Wenn Sie bereits [Py] Qt verwenden, können Sie sich für qimage2ndarray interessieren. Ab Version 1.4 (soeben veröffentlicht) wird auch PySide unterstützt, und es gibt eine winzige imsave(filename, array)-Funktion, die der von scipy ähnelt, jedoch Qt anstelle von PIL verwendet. Bei 1.3 verwenden Sie einfach etwas wie das Folgende:

qImage = array2qimage(image, normalize = False) # create QImage from ndarray
success = qImage.save(filename) # use Qt's image IO functions for saving PNG/JPG/..

(Ein weiterer Vorteil von 1.4 ist, dass es sich um eine reine Python-Lösung handelt, wodurch diese noch leichter wird.)

1
hans_meine

Verwenden Sie 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  
1
Christy Lee

Wenn Sie in der Python-Umgebung Spyder arbeiten, kann es nicht einfacher sein, als im Variablen-Explorer mit der rechten Maustaste auf das Array zu klicken und dann die Option Bild anzeigen zu wählen.

 enter image description here

Sie werden aufgefordert, das Bild in dsik zu speichern, meistens im PNG-Format.

In diesem Fall wird keine PIL-Bibliothek benötigt.

0
abunickabhi

Imageio ist eine Python-Bibliothek, die eine einfache Schnittstelle zum Lesen und Schreiben einer Vielzahl von Bilddaten bietet, einschließlich animierter Bilder, Videos, Volumendaten und wissenschaftlichen Formaten. Es ist plattformübergreifend, läuft unter Python 2.7 und 3.4+ und ist einfach zu installieren.

Dies ist ein Beispiel für ein Graustufenbild:

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)
0
Denis Rasulev