Tengo una matriz en el tipo de una matriz de Numpy. ¿Cómo lo escribiría en el disco como una imagen? Cualquier formato funciona (png, jpeg, bmp ...). Una restricción importante es que PIL no está presente.
Solo me gustaría señalar que algunas de las respuestas a continuación, y seguramente algunas de las personas que vienen y encuentran esta pregunta, no cumplen con la restricción mencionada anteriormente de estar sin PIL . Dado que algunos de los que preguntan y algunas respuestas evitan esa restricción, animo a cualquiera que esté aquí y no le importe que PIL mire a continuación, y cualquier respuesta que no sea PIL (nueva o antigua) para mencionar que se usa PIL tipo de respuesta, para distinguirse de las respuestas que cumplen con la restricción original.
Puedes usar PyPNG . Es un codificador / decodificador PNG de código abierto de Python puro (sin dependencias) y admite la escritura de matrices NumPy como imágenes.
Recuerde escalar los valores al rango correcto para PNG, generalmente 0..255. Los rangos de valores en las redes neuronales son frecuentemente 0..1 o -1..1.
Tomáš Gavenčiak
8
PyPNG es Python puro, lo que reduce sus dependencias externas, pero lo hace mucho más lento que PIL y sus clases derivadas. Por ejemplo, guardar una imagen de 3000x4000 en mi máquina tomó 4.05 segundos con PyPNG pero solo 0.59 segundos con scipy.misc.imsave (6 veces más rápido).
Zvika
@ TomášGavenčiak - scipy.misc.imsave ahora está en desuso en las versiones más recientes de Scipy. Una alternativa de algunos comentarios a continuación es usar imageio.imwrite ('image_file.jpg', array)
Psi-Ed
259
Esto usa PIL, pero tal vez algunos puedan encontrarlo útil:
EDITAR : La scipyversión actual comenzó a normalizar todas las imágenes para que min (datos) se vuelva negro y max (datos) se vuelva blanco. Esto no es deseado si los datos deben ser niveles de grises exactos o canales RGB exactos. La solución:
imsave vive en ... / scipy / misc / pilutil.py que usa PIL
denis
55
Tenga cuidado al convertir a jpg, ya que es con pérdidas y, por lo tanto, es posible que no pueda recuperar los datos exactos utilizados para generar la imagen.
Feanil
8
Esto ahora está en desuso en scipy 0.19 use - scipy.io.imwrite
g.stevo
66
"imsave está en desuso en SciPy 1.0.0, y se eliminará en 1.2.0" ( Scipy 1.1.0 doc )
noobar
15
scipy.misc.imsave está en desuso. usar import imageio; imageio.imwrite ('file_name.jpg', nmupy_array)
La imagen es un módulo de PIL. Hacer "imprimir imagen .__ archivo__"
Juh_
10
Muy útil para aquellos de nosotros que deambulamos aquí y tenemos PIL - Creo que lo usaré from PIL import Imagepara mantenerlo claro ...
sabio
44
Si tiene una imagen RGB, puede obtener la imagen usando im = Image.fromarray (A) .convert ('RGB') Más información: stackoverflow.com/questions/4711880/…
Roger Veciana
El uso del tercer eje de una matriz de uint8 para codificar RGB funciona con este método. El módulo PIL se puede instalar usando "almohada de instalación de pip".
bli
1
@Ludovico Verniani No distorsiona las imágenes, pero sí utiliza una codificación de color poco común en la que el orden de los colores es BGR en lugar de RGB.
Funciona con matplotlib 1.3.1, no sé sobre la versión inferior. Desde la cadena de documentación:
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*:AnMxN(luminance),MxNx3(RGB)orMxNx4(RGBA) array.
@HughPerkins prueba Pillow como reemplazo de PIL en Python 3
christianbrodbeck
10
import matplotlib.pyplot as plty luegoplt.imsave('name.png', array)
Alessandro Jacopson
62
Python puro (2 y 3), un fragmento sin dependencias de terceros.
Esta función escribe RGBAPNG comprimidos de color verdadero (4 bytes por píxel) .
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'')])
... Los datos deben escribirse directamente en un archivo abierto como binario, como en:
data = write_png(buf,64,64)with open("my_image.png",'wb')as fh:
fh.write(data)
Esto parece ser exactamente lo que estoy buscando, pero ¿podría agregar algunos comentarios? No veo cómo esto escribe en un archivo. ¿Tiene que escribir la salida en un archivo abierto previamente? ¡Gracias!
PhilMacKay
1
@PhilMacKay, los datos solo tienen que escribirse en un archivo binario. comentario agregado
ideasman42
1
¿Alguien puede especificar en qué formato bufse supone que debe estar la imagen ( )? No parece ser una matriz numpy ...
No, para la interfaz de pyplot, plt.figure () es superfluo. Además, solo necesita plt.show () si también desea ver una ventana de figura, en este caso solo se deseaba guardar un archivo de imagen, por lo que no era necesario llamar a show ().
DopplerShift
77
Tenga en cuenta que el archivo de imagen resultante contendrá los ejes y el área gris de la figura matlplotlib, no solo los datos de píxeles.
Dave
1
no funcionará si ejecuta su secuencia de comandos en un host remoto, si lo hace sin soporte de interfaz gráfica.
Temak
Si desea mostrar la imagen en un cuaderno, puede agregar lo siguiente: >> "desde IPython.display import Image" y luego >> "Image (filename = filename)"
Robert
Para quitar el eje:plt.axis('off')
yakout
15
Puedes usar la biblioteca 'skimage' en Python
Ejemplo:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
def saveAsPNG(array, filename):import struct
if any([len(row)!= len(array[0])for row in array]):raiseValueError,"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()
Para aquellos que buscan un ejemplo directo y totalmente funcional:
from PIL importImageimport 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 boxImage.fromarray(img).convert("RGB").save("art.png")# don't need to convert
Además, si quieres archivos JPEG de alta calidad .save(file, subsampling=0, quality=100)
matplotlib svn tiene una nueva función para guardar imágenes como solo una imagen: sin ejes, etc. También es una función muy simple para hacer backport, si no desea instalar svn (copiado directamente de image.py en matplotlib svn, eliminó el docstring por brevedad):
El mundo probablemente no necesita otro paquete para escribir una matriz numpy en un archivo PNG, pero para aquellos que no pueden obtener suficiente, recientemente puse numpngwen github:
Aquí está el primer ejemplo del examplesdirectorio del repositorio. La línea esencial es simplemente
write_png('example1.png', img)
donde imghay una matriz numpy Todo el código antes de esa línea es declaraciones de importación y código para crear 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)
Tengo curiosidad, ¿en qué se diferencia su lib de las demás? ¿Es más rápido? ¿Tiene características elegantes?
F Lekschas
Algunas características: (1) Utiliza matrices numpy. (2) Está escrito usando solo python y numpy, por lo que no requiere la instalación de una biblioteca C. (3) Puede crear archivos PNG animados. (4) Proporciona una clase para escribir animaciones matplotlib como archivos PNG animados.
Warren Weckesser
¡Gracias! Me gustaría saber cómo se compara con stackoverflow.com/a/19174800/981933 en términos de rendimiento, que también es puro Python. El primer método es superior a 2 veces más rápido que PIL, lo cual es bastante impresionante. No importa si ese no es tu objetivo :)
F Lekschas
2
Suponiendo que desea una imagen en escala de grises:
im =Image.new('L',(width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Imageio es una biblioteca de Python que proporciona una interfaz fácil para leer y escribir una amplia gama de datos de imágenes, incluidas imágenes animadas, videos, datos volumétricos y formatos científicos. Es multiplataforma, se ejecuta en Python 2.7 y 3.4+, y es fácil de instalar.
Este es un ejemplo de imagen en escala de grises:
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)
Si ya usa [Py] Qt, puede estar interesado en qimage2ndarray . A partir de la versión 1.4 (recién lanzada), PySide también es compatible, y habrá una pequeña imsave(filename, array)función similar a scipy's, pero usando Qt en lugar de PIL. Con 1.3, solo usa algo como lo siguiente:
qImage = array2qimage(image, normalize =False)# create QImage from ndarray
success = qImage.save(filename)# use Qt's image IO functions for saving PNG/JPG/..
(Otra ventaja de 1.4 es que es una solución pura de Python, lo que lo hace aún más liviano).
La versión 1.4 ya está disponible. :-) (Edité la respuesta en consecuencia.)
hans_meine
1
Si está trabajando en el entorno de Python Spyder, entonces no puede ser más fácil que simplemente hacer clic derecho en la matriz en el explorador de variables y luego elegir la opción Mostrar imagen.
Esto le pedirá que guarde la imagen en dsik, principalmente en formato PNG.
import cv2
assert mat.shape[2]==1or mat.shape[2]==3,'the third dim should be channel'
cv2.imwrite(path, mat)# note the form of data should be height - width - channel
Respuestas:
Puedes usar PyPNG . Es un codificador / decodificador PNG de código abierto de Python puro (sin dependencias) y admite la escritura de matrices NumPy como imágenes.
fuente
Esto usa PIL, pero tal vez algunos puedan encontrarlo útil:
EDITAR : La
scipy
versión actual comenzó a normalizar todas las imágenes para que min (datos) se vuelva negro y max (datos) se vuelva blanco. Esto no es deseado si los datos deben ser niveles de grises exactos o canales RGB exactos. La solución:fuente
Una respuesta usando PIL (por si acaso es útil).
dado una matriz numpy "A":
puede reemplazar "jpeg" con casi cualquier formato que desee. Más detalles sobre los formatos aquí
fuente
from PIL import Image
para mantenerlo claro ...Con
matplotlib
:Funciona con matplotlib 1.3.1, no sé sobre la versión inferior. Desde la cadena de documentación:
fuente
matplotlib.pyplot.imsave
en matplotlib 2+import matplotlib.pyplot as plt
y luegoplt.imsave('name.png', array)
Python puro (2 y 3), un fragmento sin dependencias de terceros.
Esta función escribe
RGBA
PNG comprimidos de color verdadero (4 bytes por píxel) .... Los datos deben escribirse directamente en un archivo abierto como binario, como en:
fuente
buf
se supone que debe estar la imagen ( )? No parece ser una matriz numpy ...Hay
opencv
para python ( documentación aquí ).útil si necesita hacer más procesamiento que no sea guardar.
fuente
np.zeros((10,10))
con su imagen.cmap="gray"
cuando guardo la imagen usando cv2?Si tiene matplotlib, puede hacer:
Esto guardará la trama (no las imágenes en sí).
fuente
plt.axis('off')
Puedes usar la biblioteca 'skimage' en Python
Ejemplo:
fuente
scipy.misc
da advertencia de desaprobación sobre laimsave
función y sugiere el uso de en suimageio
lugar.fuente
Anexo a la respuesta de @ ideasman42:
Entonces puedes hacer:
Produciendo
test_grid.png
:(La transparencia también funciona al reducir el byte alto de
0xff
).fuente
Para aquellos que buscan un ejemplo directo y totalmente funcional:
Además, si quieres archivos JPEG de alta calidad
.save(file, subsampling=0, quality=100)
fuente
matplotlib svn tiene una nueva función para guardar imágenes como solo una imagen: sin ejes, etc. También es una función muy simple para hacer backport, si no desea instalar svn (copiado directamente de image.py en matplotlib svn, eliminó el docstring por brevedad):
fuente
El mundo probablemente no necesita otro paquete para escribir una matriz numpy en un archivo PNG, pero para aquellos que no pueden obtener suficiente, recientemente puse
numpngw
en github:https://github.com/WarrenWeckesser/numpngw
y en pypi: https://pypi.python.org/pypi/numpngw/
La única dependencia externa es numpy.
Aquí está el primer ejemplo del
examples
directorio del repositorio. La línea esencial es simplementedonde
img
hay una matriz numpy Todo el código antes de esa línea es declaraciones de importación y código para crearimg
.Aquí está el archivo PNG que crea:
fuente
Suponiendo que desea una imagen en escala de grises:
fuente
Imageio es una biblioteca de Python que proporciona una interfaz fácil para leer y escribir una amplia gama de datos de imágenes, incluidas imágenes animadas, videos, datos volumétricos y formatos científicos. Es multiplataforma, se ejecuta en Python 2.7 y 3.4+, y es fácil de instalar.
Este es un ejemplo de imagen en escala de grises:
fuente
Si ya usa [Py] Qt, puede estar interesado en qimage2ndarray . A partir de la versión 1.4 (recién lanzada), PySide también es compatible, y habrá una pequeña
imsave(filename, array)
función similar a scipy's, pero usando Qt en lugar de PIL. Con 1.3, solo usa algo como lo siguiente:(Otra ventaja de 1.4 es que es una solución pura de Python, lo que lo hace aún más liviano).
fuente
Si está trabajando en el entorno de Python Spyder, entonces no puede ser más fácil que simplemente hacer clic derecho en la matriz en el explorador de variables y luego elegir la opción Mostrar imagen.
Esto le pedirá que guarde la imagen en dsik, principalmente en formato PNG.
La biblioteca PIL no será necesaria en este caso.
fuente
Uso
cv2.imwrite
.fuente
para guardar una matriz numpy como imagen, U tiene varias opciones:
1) lo mejor de otro: OpenCV
2) Matplotlib
3) PIL
4) ...
fuente