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.
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.
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')
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.
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)
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.
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:
(Transparenz funktioniert auch, indem das High-Byte von 0xff
reduziert wird.)
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)
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)
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)
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)
Angenommen, Sie möchten ein Graustufenbild:
im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
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:
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.)
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
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.
Sie werden aufgefordert, das Bild in dsik zu speichern, meistens im PNG-Format.
In diesem Fall wird keine PIL-Bibliothek benötigt.
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)