Domanda

Ho una matrice del tipo di una matrice Numpy. Come vorrei scrivere su disco come immagine? Eventuali opere (PNG, JPEG, BMP ...). Un vincolo importante è che PIL non è presente.

È stato utile?

Soluzione

È possibile utilizzare PyPNG . Si tratta di un Python puro (senza dipendenze) open source PNG encoder / decoder e supporta la scrittura array NumPy come immagini.

Altri suggerimenti

Questo utilizza PIL, ma forse alcuni potrebbero trovare utile:

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

Modifica : La versione corrente scipy iniziato a normalizzare tutte le immagini in modo che min (dati) diventano neri e massima (dati) diventano bianchi. Questo è indesiderato se i dati devono essere esatti livelli di grigio o canali RGB esatte. La soluzione:

import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')

Una risposta utilizzando PIL (nel caso in cui è utile).

dato un array di NumPy "A":

from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")

è possibile sostituire "JPEG" con praticamente qualsiasi formato che si desidera. Maggiori informazioni su formati qui

Con matplotlib:

import matplotlib

matplotlib.image.imsave('name.png', array)

Funziona con matplotlib 1.3.1, non so sulla versione inferiore. Dal 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.

 entrare descrizione dell'immagine qui

Pure Python (2 e 3), un frammento senza 3rd dipendenze del partito.

Questa funzione scrive compresso, true-color (4 byte per pixel) RGBA di 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'')])

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

C'è opencv per Python ( documentazione qui ) .

import cv2
import numpy as np

cv2.imwrite("filename.png", np.zeros((10,10)))

utile se è necessario fare di più l'elaborazione altro che salvare.

Se avete matplotlib, si può fare:

import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)

Ciò farà risparmiare la trama (non le immagini stesso). entrare image description qui

Addendum al di @ ideasman42 risposta:

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

Così si può fare:

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

La produzione test_grid.png:

Grid di rosso, giallo, scuro-aqua, grigio

(La trasparenza funziona anche, riducendo il byte alto da 0xff.)

È possibile utilizzare 'skimage' biblioteca in Python

Esempio:

from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)

scipy.misc dà avvertimento disapprovazione sulla funzione imsave e suggerisce l'utilizzo di imageio invece.

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

matplotlib svn ha una nuova funzione per salvare le immagini come solo un'immagine - nessun assi ecc E 'una funzione molto semplice da backport troppo, se non si desidera installare svn (copiato direttamente dal image.py in matplotlib svn , rimosso il docstring 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)

Per chi cerca un esempio di completamente funzionante diretta:

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 alta qualità iOffer jpeg .save(file, subsampling=0, quality=100)

Il mondo probabilmente non ha bisogno di ancora un altro pacchetto per la scrittura di una matrice NumPy a un file PNG, ma per chi non ne ha mai abbastanza, di recente ho messo numpngw su github:

https://github.com/WarrenWeckesser/numpngw

e PyPI: https://pypi.python.org/pypi/numpngw/

L'unica dipendenza esterna è NumPy.

Ecco il primo esempio dalla directory examples del repository. La linea essenziale è semplicemente

write_png('example1.png', img)

dove img è una matrice NumPy. Tutto il codice prima che la linea è dichiarazioni e codice per creare img importazione.

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:

example1.png

Supponendo che si desidera un'immagine in scala di grigi:

im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")

Se vi capita di usare [Py] Qt già, si può essere interessati a qimage2ndarray . A partire dalla versione 1.4 (appena uscito), PySide è supportato pure, e ci sarà una piccola funzione di imsave(filename, array) simile a SciPy di, 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 pitone puro, che rende ancora più leggero.)

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  

Se si lavora in un ambiente python Spyder, allora non può ottenere più facile che basta fare clic destro la matrice in Esplora risorse variabili, e quindi scegliere Mostra opzione Immagine.

entrare descrizione dell'immagine qui

Questo vi chiederà di salvare l'immagine a dsik, per lo più in formato PNG.

libreria PIL non sarà necessario in questo caso.

ImageIO è una libreria Python che fornisce un'interfaccia facile da leggere e scrivere una vasta gamma di dati di immagine , comprese le immagini animate, video, dati volumetrici, e formati scientifici. E 'cross-platform, gira su Python 2.7 e 3.4+, ed è facile da installare.

Questo è ad esempio per un'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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top