Enregistrement d'un tableau Numpy en tant qu'image
261
J'ai une matrice dans le type d'un tableau Numpy. Comment pourrais-je l'écrire sur le disque en tant qu'image? Tout format fonctionne (png, jpeg, bmp ...). Une contrainte importante est que le PIL n'est pas présent.
Je voudrais juste noter que certaines des réponses ci-dessous, et sûrement certaines des personnes venant et trouvant cette question, ne rencontrent pas la contrainte listée ci-dessus d'être sans PIL . Étant donné que certains demandeurs et certaines réponses évitent tous deux cette contrainte, j'encourage tous ceux qui sont ici et cela ne me dérange pas d'avoir PIL à regarder ci-dessous, et toutes les réponses non-PIL (nouvelles ou anciennes) à mentionner qu'elles sont un PIL-est utilisé type de réponse, pour se distinguer des réponses répondant à la contrainte d'origine.
Vous pouvez utiliser PyPNG . Il s'agit d'un pur encodeur / décodeur PNG open source Python (sans dépendances) et il prend en charge l' écriture de tableaux NumPy sous forme d'images.
N'oubliez pas de mettre à l'échelle les valeurs dans la bonne plage pour PNG, généralement 0..255. Les plages de valeurs dans les réseaux de neurones sont souvent de 0..1 ou -1..1.
Tomáš Gavenčiak
8
PyPNG est pur Python, ce qui réduit ses dépendances externes, mais le rend beaucoup plus lent que PIL et ses classes dérivées. Par exemple, enregistrer une image 3000x4000 sur ma machine a pris 4,05 secondes avec PyPNG mais seulement 0,59 secondes avec scipy.misc.imsave (6x plus rapide).
Zvika
@ TomášGavenčiak - scipy.misc.imsave est désormais déconseillé dans les nouvelles versions de Scipy. Une alternative quelques commentaires ci-dessous est d'utiliser imageio.imwrite ('image_file.jpg', array)
Psi-Ed
259
Cela utilise PIL, mais certains pourraient le trouver utile:
EDIT : La scipyversion actuelle a commencé à normaliser toutes les images afin que min (données) deviennent noires et max (données) deviennent blanches. Ceci n'est pas souhaité si les données doivent être des niveaux de gris exacts ou des canaux RVB exacts. La solution:
imsave vit dans ... / scipy / misc / pilutil.py qui utilise PIL
denis
5
Soyez prudent lors de la conversion en jpg car il est avec perte et vous risquez donc de ne pas pouvoir récupérer les données exactes utilisées pour générer l'image.
Feanil
8
Ceci est désormais obsolète dans l'utilisation de scipy 0.19 - scipy.io.imwrite
g.stevo
6
"imsave est déconseillé dans SciPy 1.0.0 et sera supprimé dans 1.2.0" ( doc Scipy 1.1.0 )
noobar
15
scipy.misc.imsave est obsolète. utiliser import imageio; imageio.imwrite ('file_name.jpg', nmupy_array)
ChaosPredictor
228
Une réponse en utilisant PIL (juste au cas où cela serait utile).
étant donné un tableau numpy "A":
from PIL importImage
im =Image.fromarray(A)
im.save("your_file.jpeg")
vous pouvez remplacer "jpeg" par presque n'importe quel format souhaité. Plus de détails sur les formats ici
L'image est un module de PIL. Faire "imprimer l'image .__ fichier__"
Juh_
10
Très utile pour ceux d'entre nous qui se sont promenés ici et ont PIL - Je pense que je vais utiliser from PIL import Imagepour être clair ...
sage
4
Si vous avez une image RVB, vous pouvez obtenir l'image en utilisant im = Image.fromarray (A) .convert ('RGB') Plus d'infos: stackoverflow.com/questions/4711880/…
Roger Veciana
L'utilisation du troisième axe d'un tableau de uint8 pour coder RVB fonctionne avec cette méthode. Le module PIL peut être installé à l'aide d'un "oreiller d'installation de pip".
bli
1
@Ludovico Verniani Il ne déforme pas les images, mais il utilise un codage couleur quelque peu inhabituel dans lequel l'ordre des couleurs est BGR plutôt que RVB.
Fonctionne avec matplotlib 1.3.1, je ne connais pas la version inférieure. De la 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*:AnMxN(luminance),MxNx3(RGB)orMxNx4(RGBA) array.
En utilisant cela. Mais souffrant d'une fuite de mémoire
SolessChong
matplotlib.imsave () dans les versions plus récentes
Vinay Lodha
6
C'est matplotlib.pyplot.imsavedans matplotlib 2+
Aleksei Petrenko
1
@HughPerkins essaie Pillow en remplacement de PIL dans Python 3
christianbrodbeck
10
import matplotlib.pyplot as pltpuisplt.imsave('name.png', array)
Alessandro Jacopson
62
Pure Python (2 & 3), un extrait sans dépendances tierces.
Cette fonction écrit des fichiers RGBAPNG compressés en couleurs vraies (4 octets par 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'')])
... Les données doivent être écrites directement dans un fichier ouvert en binaire, comme dans:
data = write_png(buf,64,64)with open("my_image.png",'wb')as fh:
fh.write(data)
Cela semble être exactement ce que je recherche, mais pourriez-vous ajouter quelques commentaires? Je ne vois pas comment cela écrit dans un fichier. Devez-vous écrire la sortie dans un fichier précédemment ouvert? Merci!
PhilMacKay
1
@PhilMacKay, les données doivent juste être écrites dans un fichier binaire. commentaire ajouté.
ideasman42
1
Quelqu'un peut-il spécifier dans quel format l'image ( buf) est censée être? Il ne semble pas être un tableau engourdi ...
Pourquoi un tableau de taille 10? Qu'est-ce qui a conduit au choix de 10 dans cette solution?
Gathide
3
@Gathide Juste comme un exemple d'écriture d'une matrice numpy arbitraire dans un fichier. Dans la vraie vie, remplacez np.zeros((10,10))par votre image.
Xocoatzin
5
Comment puis-je ajouter quelque chose comme cmap="gray"lorsque j'enregistre l'image à l'aide de cv2?
Mona Jalal
@Xocoatzin Lien brisé?
jtlz2
1
@ jtlz2 Lien mis à jour.
Xocoatzin
30
Si vous avez matplotlib, vous pouvez faire:
import matplotlib.pyplot as plt
plt.imshow(matrix)#Needs to be in row,col order
plt.savefig(filename)
Cela sauvera l'intrigue (pas les images elles-mêmes).
Non, pour l'interface pyplot, le plt.figure () est superflu. De plus, vous n'avez besoin de plt.show () que si vous souhaitez également voir une fenêtre de figure - dans ce cas, seule la sauvegarde d'un fichier image était souhaitée, il n'était donc pas nécessaire d'appeler show ().
DopplerShift
7
Notez que le fichier d'image résultant contiendra les axes et la zone grise de la figure matlplotlib - pas seulement les données de pixels.
Dave
1
ne fonctionnera pas si vous exécutez votre script sur un hôte distant, en y accédant sans prise en charge de l'interface graphique.
Temak
Si vous souhaitez afficher l'image dans un bloc-notes, vous pouvez ajouter ce qui suit: >> "depuis IPython.display import Image" puis >> "Image (filename = filename)"
Robert
Pour retirer l'axe:plt.axis('off')
yakout
15
Vous pouvez utiliser la bibliothèque 'skimage' en Python
Exemple:
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()
Pour ceux qui recherchent un exemple direct pleinement fonctionnel:
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
aussi, si vous voulez des jpeg de haute qualité .save(file, subsampling=0, quality=100)
matplotlib svn a une nouvelle fonction pour enregistrer les images comme une simple image - pas d'axes etc. c'est une fonction très simple à rétroporter aussi, si vous ne voulez pas installer svn (copié directement depuis image.py dans matplotlib svn, supprimé le docstring pour plus de concision):
Le monde n'a probablement pas encore besoin d'un autre paquet pour écrire un tableau numpy dans un fichier PNG, mais pour ceux qui n'en ont pas assez, j'ai récemment mis en place numpngwsur github:
Voici le premier exemple du examplesrépertoire du référentiel. La ligne essentielle est tout simplement
write_png('example1.png', img)
où imgest un tableau numpy. Tout le code avant cette ligne est des instructions d'importation et du code à créer 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)
Je suis curieux, en quoi votre bibliothèque est-elle différente des autres? Est-ce plus rapide? At-il des fonctionnalités de fantaisie?
F Lekschas
Quelques fonctionnalités: (1) Il utilise des tableaux numpy. (2) Il est écrit en utilisant uniquement python et numpy, il ne nécessite donc pas l'installation d'une bibliothèque C. (3) Il peut créer des fichiers PNG animés. (4) Il fournit une classe pour écrire des animations matplotlib sous forme de fichiers PNG animés.
Warren Weckesser
Merci! Je serais curieux de voir comment il se compare à stackoverflow.com/a/19174800/981933 en termes de performances, qui est également du pur python. L'ancienne méthode est au-dessus de 2x plus rapide que PIL, ce qui est assez génial.
Peu importe
2
En supposant que vous souhaitiez une image en niveaux de gris:
im =Image.new('L',(width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Imageio est une bibliothèque Python qui fournit une interface simple pour lire et écrire une large gamme de données d'images, y compris des images animées, des vidéos, des données volumétriques et des formats scientifiques. Il est multiplateforme, fonctionne sur Python 2.7 et 3.4+, et est facile à installer.
Voici un exemple d'image en niveaux de gris:
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 vous utilisez déjà [Py] Qt, vous pourriez être intéressé par qimage2ndarray . À partir de la version 1.4 (qui vient d'être publiée), PySide est également pris en charge, et il y aura une minuscule imsave(filename, array)fonction similaire à scipy's, mais utilisant Qt au lieu de PIL. Avec 1.3, utilisez simplement quelque chose comme ceci:
qImage = array2qimage(image, normalize =False)# create QImage from ndarray
success = qImage.save(filename)# use Qt's image IO functions for saving PNG/JPG/..
(Un autre avantage de la version 1.4 est qu'il s'agit d'une solution python pure, ce qui la rend encore plus légère.)
La version 1.4 est maintenant disponible. :-) (J'ai modifié la réponse en conséquence.)
hans_meine
1
Si vous travaillez dans un environnement python Spyder, cela ne peut pas être plus facile que de simplement cliquer avec le bouton droit sur le tableau dans l'explorateur de variables, puis choisissez l'option Afficher l'image.
Cela vous demandera d'enregistrer l'image sur dsik, principalement au format PNG.
La bibliothèque PIL ne sera pas nécessaire dans ce cas.
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
Réponses:
Vous pouvez utiliser PyPNG . Il s'agit d'un pur encodeur / décodeur PNG open source Python (sans dépendances) et il prend en charge l' écriture de tableaux NumPy sous forme d'images.
la source
Cela utilise PIL, mais certains pourraient le trouver utile:
EDIT : La
scipy
version actuelle a commencé à normaliser toutes les images afin que min (données) deviennent noires et max (données) deviennent blanches. Ceci n'est pas souhaité si les données doivent être des niveaux de gris exacts ou des canaux RVB exacts. La solution:la source
Une réponse en utilisant PIL (juste au cas où cela serait utile).
étant donné un tableau numpy "A":
vous pouvez remplacer "jpeg" par presque n'importe quel format souhaité. Plus de détails sur les formats ici
la source
from PIL import Image
pour être clair ...Avec
matplotlib
:Fonctionne avec matplotlib 1.3.1, je ne connais pas la version inférieure. De la docstring:
la source
matplotlib.pyplot.imsave
dans matplotlib 2+import matplotlib.pyplot as plt
puisplt.imsave('name.png', array)
Pure Python (2 & 3), un extrait sans dépendances tierces.
Cette fonction écrit des fichiers
RGBA
PNG compressés en couleurs vraies (4 octets par pixel) .... Les données doivent être écrites directement dans un fichier ouvert en binaire, comme dans:
la source
buf
) est censée être? Il ne semble pas être un tableau engourdi ...Il y a
opencv
pour python ( documentation ici ).utile si vous devez faire plus de traitement que l'enregistrement.
la source
np.zeros((10,10))
par votre image.cmap="gray"
lorsque j'enregistre l'image à l'aide de cv2?Si vous avez matplotlib, vous pouvez faire:
Cela sauvera l'intrigue (pas les images elles-mêmes).
la source
plt.axis('off')
Vous pouvez utiliser la bibliothèque 'skimage' en Python
Exemple:
la source
scipy.misc
donne un avertissement de dépréciation sur laimsave
fonction et suggère l'utilisation deimageio
plutôt.la source
Addendum à la réponse de @ ideasman42:
Vous pouvez donc faire:
Produire
test_grid.png
:(La transparence fonctionne également, en réduisant l'octet de poids fort de
0xff
.)la source
Pour ceux qui recherchent un exemple direct pleinement fonctionnel:
aussi, si vous voulez des jpeg de haute qualité
.save(file, subsampling=0, quality=100)
la source
matplotlib svn a une nouvelle fonction pour enregistrer les images comme une simple image - pas d'axes etc. c'est une fonction très simple à rétroporter aussi, si vous ne voulez pas installer svn (copié directement depuis image.py dans matplotlib svn, supprimé le docstring pour plus de concision):
la source
Le monde n'a probablement pas encore besoin d'un autre paquet pour écrire un tableau numpy dans un fichier PNG, mais pour ceux qui n'en ont pas assez, j'ai récemment mis en place
numpngw
sur github:https://github.com/WarrenWeckesser/numpngw
et sur pypi: https://pypi.python.org/pypi/numpngw/
La seule dépendance externe est numpy.
Voici le premier exemple du
examples
répertoire du référentiel. La ligne essentielle est tout simplementoù
img
est un tableau numpy. Tout le code avant cette ligne est des instructions d'importation et du code à créerimg
.Voici le fichier PNG qu'il crée:
la source
En supposant que vous souhaitiez une image en niveaux de gris:
la source
Imageio est une bibliothèque Python qui fournit une interface simple pour lire et écrire une large gamme de données d'images, y compris des images animées, des vidéos, des données volumétriques et des formats scientifiques. Il est multiplateforme, fonctionne sur Python 2.7 et 3.4+, et est facile à installer.
Voici un exemple d'image en niveaux de gris:
la source
Si vous utilisez déjà [Py] Qt, vous pourriez être intéressé par qimage2ndarray . À partir de la version 1.4 (qui vient d'être publiée), PySide est également pris en charge, et il y aura une minuscule
imsave(filename, array)
fonction similaire à scipy's, mais utilisant Qt au lieu de PIL. Avec 1.3, utilisez simplement quelque chose comme ceci:(Un autre avantage de la version 1.4 est qu'il s'agit d'une solution python pure, ce qui la rend encore plus légère.)
la source
Si vous travaillez dans un environnement python Spyder, cela ne peut pas être plus facile que de simplement cliquer avec le bouton droit sur le tableau dans l'explorateur de variables, puis choisissez l'option Afficher l'image.
Cela vous demandera d'enregistrer l'image sur dsik, principalement au format PNG.
La bibliothèque PIL ne sera pas nécessaire dans ce cas.
la source
Utilisez
cv2.imwrite
.la source
pour enregistrer un tableau numpy en tant qu'image, vous avez plusieurs choix:
1) le meilleur des autres: OpenCV
2) Matplotlib
3) PIL
4) ...
la source