Risparmiando una matrice Numpy come immagine
Domanda
Ho una matrice del tipo di una matrice Numpy. Come vorrei scrivere su disco come immagine? Eventuali opere (PNG, JPEG, BMP ...). Un vincolo importante è che PIL non è presente.
Altri suggerimenti
Questo utilizza PIL, ma forse alcuni potrebbero trovare utile:
import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)
Modifica : La versione corrente scipy
iniziato a normalizzare tutte le immagini in modo che min (dati) diventano neri e massima (dati) diventano bianchi. Questo è indesiderato se i dati devono essere esatti livelli di grigio o canali RGB esatte. La soluzione:
import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
Con matplotlib
:
import matplotlib
matplotlib.image.imsave('name.png', array)
Funziona con matplotlib 1.3.1, non so sulla versione inferiore. Dal 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 e 3), un frammento senza 3rd dipendenze del partito.
Questa funzione scrive compresso, true-color (4 byte per pixel) RGBA
di 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'')])
... I dati devono essere scritti direttamente in un file aperto come binario, come in:
data = write_png(buf, 64, 64)
with open("my_image.png", 'wb') as fd:
fd.write(data)
- Fonte originale
- Vedi anche: Rust Port da questa domanda .
- Esempio di utilizzo grazie alla @Evgeni Sergeev: https://stackoverflow.com/a/21034111/432509
C'è opencv
per Python ( documentazione qui ) .
import cv2
import numpy as np
cv2.imwrite("filename.png", np.zeros((10,10)))
utile se è necessario fare di più l'elaborazione altro che salvare.
Addendum al di @ ideasman42 risposta:
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()
Così si può fare:
saveAsPNG([[0xffFF0000, 0xffFFFF00],
[0xff00aa77, 0xff333333]], 'test_grid.png')
La produzione test_grid.png
:
(La trasparenza funziona anche, riducendo il byte alto da 0xff
.)
È possibile utilizzare 'skimage' biblioteca in Python
Esempio:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
scipy.misc
dà avvertimento disapprovazione sulla funzione imsave
e suggerisce l'utilizzo di imageio
invece.
import imageio
imageio.imwrite('image_name.png', img)
matplotlib svn ha una nuova funzione per salvare le immagini come solo un'immagine - nessun assi ecc E 'una funzione molto semplice da backport troppo, se non si desidera installare svn (copiato direttamente dal image.py in matplotlib svn , rimosso il docstring per brevità):
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)
Per chi cerca un esempio di completamente funzionante diretta:
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
Inoltre, se si desidera alta qualità iOffer jpeg
.save(file, subsampling=0, quality=100)
Il mondo probabilmente non ha bisogno di ancora un altro pacchetto per la scrittura di una matrice NumPy a un file PNG, ma per chi non ne ha mai abbastanza, di recente ho messo numpngw
su github:
https://github.com/WarrenWeckesser/numpngw
e PyPI: https://pypi.python.org/pypi/numpngw/
L'unica dipendenza esterna è NumPy.
Ecco il primo esempio dalla directory examples
del repository. La linea essenziale è semplicemente
write_png('example1.png', img)
dove img
è una matrice NumPy. Tutto il codice prima che la linea è dichiarazioni e codice per creare img
importazione.
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)
Ecco il file PNG che crea:
Supponendo che si desidera un'immagine in scala di grigi:
im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Se vi capita di usare [Py] Qt già, si può essere interessati a qimage2ndarray . A partire dalla versione 1.4 (appena uscito), PySide è supportato pure, e ci sarà una piccola funzione di imsave(filename, array)
simile a SciPy di, ma usando Qt, invece di PIL. Con 1.3, basta usare qualcosa di simile al seguente:
qImage = array2qimage(image, normalize = False) # create QImage from ndarray
success = qImage.save(filename) # use Qt's image IO functions for saving PNG/JPG/..
(Un altro vantaggio di 1,4 è che si tratta di una soluzione pitone puro, che rende ancora più leggero.)
Usa 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
Se si lavora in un ambiente python Spyder, allora non può ottenere più facile che basta fare clic destro la matrice in Esplora risorse variabili, e quindi scegliere Mostra opzione Immagine.
Questo vi chiederà di salvare l'immagine a dsik, per lo più in formato PNG.
libreria PIL non sarà necessario in questo caso.
ImageIO è una libreria Python che fornisce un'interfaccia facile da leggere e scrivere una vasta gamma di dati di immagine , comprese le immagini animate, video, dati volumetrici, e formati scientifici. E 'cross-platform, gira su Python 2.7 e 3.4+, ed è facile da installare.
Questo è ad esempio per un'immagine in scala di grigi:
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)