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.
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.
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.
Cela utilise PIL, mais certains pourraient le trouver utile:
import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)
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:
import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
Une réponse en utilisant PIL (juste au cas où cela serait utile).
étant donné un tableau numpy "A":
from PIL import Image
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
from PIL import Image
pour être clair ...
Avec matplotlib
:
import matplotlib
matplotlib.image.imsave('name.png', array)
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*:
An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array.
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) .
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)
buf
) est censée être? Il ne semble pas être un tableau engourdi ...
Il y a opencv
pour python ( documentation ici ).
import cv2
import numpy as np
cv2.imwrite("filename.png", np.zeros((10,10)))
utile si vous devez faire plus de traitement que l'enregistrement.
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:
import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)
plt.axis('off')
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)
Addendum à la réponse de @ 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()
Vous pouvez donc faire:
saveAsPNG([[0xffFF0000, 0xffFFFF00],
[0xff00aa77, 0xff333333]], 'test_grid.png')
Produire test_grid.png
:
(La transparence fonctionne également, en réduisant l'octet de poids fort de 0xff
.)
Pour ceux qui recherchent un exemple direct pleinement fonctionnel:
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
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):
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)
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 simplement
write_png('example1.png', img)
où img
est 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)
Voici le fichier PNG qu'il crée:
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.)
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.
Utilisez 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
pour enregistrer un tableau numpy en tant qu'image, vous avez plusieurs choix:
1) le meilleur des autres: 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) ...