Ho una matrice nel tipo di un array Numpy. Come lo scriverei su disco come immagine? Qualsiasi formato funziona (png, jpeg, bmp ...). Un vincolo importante è che il PIL non è presente.
Ho una matrice nel tipo di un array Numpy. Come lo scriverei su disco come immagine? Qualsiasi formato funziona (png, jpeg, bmp ...). Un vincolo importante è che il PIL non è presente.
Risposte:
Puoi usare PyPNG . È un codificatore / decodificatore PNG open source Python puro (senza dipendenze) e supporta la scrittura di array NumPy come immagini.
Questo utilizza PIL, ma forse alcuni potrebbero trovarlo utile:
import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)
EDIT : la scipy
versione corrente ha iniziato a normalizzare tutte le immagini in modo che min (dati) diventino neri e max (dati) diventino bianchi. Ciò è indesiderato se i dati devono essere livelli di grigio esatti o canali RGB esatti. La soluzione:
import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
Una risposta usando PIL (nel caso sia utile).
dato un array intorpidito "A":
from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")
puoi sostituire "jpeg" con quasi tutti i formati che desideri. Maggiori dettagli sui formati qui
from PIL import Image
per tenerlo chiaro ...
Con matplotlib
:
import matplotlib
matplotlib.image.imsave('name.png', array)
Funziona con matplotlib 1.3.1, non conosco la versione precedente. Dalla dotstring:
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.
matplotlib.pyplot.imsave
in matplotlib 2+
import matplotlib.pyplot as plt
e poiplt.imsave('name.png', array)
Pure Python (2 e 3), uno snippet senza dipendenze di terze parti.
Questa funzione scrive RGBA
PNG compressi a colori reali (4 byte per pixel) .
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 fh:
fh.write(data)
buf
dovrebbe essere l'immagine ( )? Non sembra essere un array insensibile ...
C'è opencv
per Python ( documentazione qui ).
import cv2
import numpy as np
cv2.imwrite("filename.png", np.zeros((10,10)))
utile se è necessario eseguire più elaborazioni oltre al salvataggio.
np.zeros((10,10))
con la tua immagine.
cmap="gray"
per quando salvo l'immagine usando cv2?
Se hai matplotlib, puoi fare:
import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)
plt.axis('off')
Puoi usare la libreria 'skimage' in Python
Esempio:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
Addendum alla risposta di @ 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()
Quindi puoi fare:
saveAsPNG([[0xffFF0000, 0xffFFFF00],
[0xff00aa77, 0xff333333]], 'test_grid.png')
Produzione test_grid.png
:
(La trasparenza funziona anche, riducendo il byte alto da 0xff
.)
Per chi cerca un esempio diretto e perfettamente funzionante:
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 jpeg di alta qualità
.save(file, subsampling=0, quality=100)
matplotlib svn ha una nuova funzione per salvare le immagini come una sola immagine - niente assi ecc. è anche una funzione molto semplice per eseguire il backport, se non si desidera installare svn (copiato direttamente da image.py in matplotlib svn, rimosso il documentazione 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)
Il mondo probabilmente non ha bisogno di un altro pacchetto per scrivere un array numpy in un file PNG, ma per quelli che non ne hanno abbastanza, di recente ho messo numpngw
su github:
https://github.com/WarrenWeckesser/numpngw
e su pypi: https://pypi.python.org/pypi/numpngw/
L'unica dipendenza esterna è intorpidita.
Ecco il primo esempio dalla examples
directory del repository. La linea essenziale è semplicemente
write_png('example1.png', img)
dove img
è un array intorpidito. Tutto il codice prima di quella riga è costituito da istruzioni di importazione e codice da creare 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)
Ecco il file PNG che crea:
Supponendo che desideri un'immagine in scala di grigi:
im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Imageio è una libreria Python che fornisce un'interfaccia semplice per leggere e scrivere una vasta gamma di dati di immagini, tra cui immagini animate, video, dati volumetrici e formati scientifici. È multipiattaforma, funziona su Python 2.7 e 3.4+ ed è facile da installare.
Questo è un esempio per l'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)
Se usi già [Py] Qt, potresti essere interessato a qimage2ndarray . A partire dalla versione 1.4 (appena rilasciata), è supportato anche PySide e ci sarà una piccola imsave(filename, array)
funzione simile a Scipy, 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 in puro pitone, che lo rende ancora più leggero.)
Se lavori in ambiente Python Spyder, non può essere più semplice che fare semplicemente clic con il pulsante destro del mouse sull'array in Esplora risorse, quindi scegliere l'opzione Mostra immagine.
Questo ti chiederà di salvare l'immagine su dsik, principalmente in formato PNG.
In questo caso la libreria PIL non sarà necessaria.
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
per salvare una matrice numpy come immagine, U ha diverse scelte:
1) il meglio dell'altro: OpenCV
import cv2 cv2.imwrite('file name with extension(like .jpg)', numpy_array)
2) Matplotlib
from matplotlib import pyplot as plt plt.imsave('file name with extension(like .jpg)', numpy_array)
3) PIL
from PIL import Image image = Image.fromarray(numpy_array) image.save('file name with extension(like .jpg)')
4) ...