web-dev-qa-db-fra.com

Enregistrement d'un tableau Numpy en tant qu'image

J'ai une matrice dans le type d'un tableau de Numpy. Comment pourrais-je l'écrire sur le disque en tant qu'image? Tous les formats fonctionnent (png, jpeg, bmp ...). Une contrainte importante est que la LIP n'est pas présente.

192
M456

Vous pouvez utiliser PyPNG . Il s’agit d’un codeur/décodeur PNG open source pur Python (sans dépendance) et il prend en charge l’écriture de tableaux NumPy sous forme d’images.

44
dF.

Cela utilise PIL, mais peut-être que certains le trouveront utile:

import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)

EDIT: La version scipy actuelle a commencé à normaliser toutes les images de sorte que min (données) devienne noir et max (données) devienne blanc. Cela est indésirable 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')
220
Steve Tjoa

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. Plus de détails sur les formats ici

138
migas

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.

 enter image description here

51

Pure Python (2 & 3), un extrait sans dépendances de tiers.

Cette fonction écrit en format TrueColor compressé (4 octets par pixel) RGBA 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'')])

... 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 fd:
    fd.write(data)

51
ideasman42

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 avez besoin de traiter davantage que d’enregistrer.

28
Xocoatzin

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 permettra d'économiser l'intrigue (pas les images elle-même).  enter image description here

27
DopplerShift

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()

Alors tu peux faire:

saveAsPNG([[0xffFF0000, 0xffFFFF00],
           [0xff00aa77, 0xff333333]], 'test_grid.png')

Produire test_grid.png:

Grid of red, yellow, dark-aqua, grey

(La transparence fonctionne également en réduisant l'octet haut de 0xff.)

11
Evgeni Sergeev

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)
9
PURNENDU MISHRA

scipy.misc donne un avertissement de désapprobation concernant la fonction imsave et suggère d'utiliser plutôt imageio.

import imageio
imageio.imwrite('image_name.png', img)
4
Sefa

matplotlib svn a une nouvelle fonction pour enregistrer les images sous forme d'image - pas d'axes, etc. C'est une fonction très simple pour sauvegarder aussi, si vous ne souhaitez pas installer svn 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)
4
Autoplectic

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")
2

Le monde n'a probablement pas besoin d'un autre paquet pour écrire un tableau numpy dans un fichier PNG, mais pour ceux qui n'en ont jamais assez, j'ai récemment mis 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 tiré du répertoire examples du référentiel. La ligne essentielle est simplement

write_png('example1.png', img)

img est un tableau numpy. Tout le code avant cette ligne est constitué d'instructions d'importation et de code permettant de 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:

 example1.png

2
Warren Weckesser

Si vous utilisez déjà [Py] Qt, vous pourriez être intéressé par qimage2ndarray . À partir de la version 1.4 (qui vient de paraître), PySide est également pris en charge. Il y aura une fonction imsave(filename, array) semblable à celle de scipy, mais utilisant Qt au lieu de PIL. Avec 1.3, utilisez simplement quelque chose comme ce qui suit:

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 pure en python, ce qui la rend encore plus légère.)

1
hans_meine

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  
1
Christy Lee

Si vous travaillez dans l’environnement Spyder de l’environnement python, il n’est pas plus facile de cliquer avec le bouton droit de la souris sur le tableau dans la variable Explorateur, puis de choisir l’option Afficher l’image.

 enter image description here

Cela vous demandera de sauvegarder l'image sur dsik, principalement au format PNG.

La bibliothèque PIL ne sera pas nécessaire dans ce cas.

0
abunickabhi

Imageio est une bibliothèque Python qui fournit une interface simple pour lire et écrire un large éventail de données d’image, notamment des images animées, des vidéos, des données volumétriques et des formats scientifiques. Il est multi-plateforme, 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)
0
Denis Rasulev