2011-10-14 19 views
36

Ho un'immagine RGB. Voglio convertirlo in array numpy. Ho fatto il seguentecome convertire un'immagine RGB in array numpy?

im = cv.LoadImage("abc.tiff") 
a = numpy.asarray(im) 

crea un array senza forma. Suppongo sia un oggetto iplimage.

Come fare?

Grazie

+2

Se 'cv' è il modulo OpenCV, allora si dovrebbe contrassegnare come tale. Questo link può aiutare: http://opencv.willowgarage.com/documentation/python/cookbook.html#numpy-and-opencv – Paul

risposta

55

È possibile utilizzare più recente interfaccia OpenCV python (se non mi sbaglio è disponibile dal OpenCV 2.2). Esso utilizza nativamente array NumPy:

import cv2 
im = cv2.imread("abc.tiff") 
print type(im) 

risultato:

<type 'numpy.ndarray'> 
+1

cv2 è la nuova interfaccia ed è molto più facile da usare IMHO. È progettato per rappresentare più da vicino le classi C++. – Neon22

+6

Attenzione che cv2.imread() restituisce una matrice numpy in BGR non RGB. – pnd

+0

Funzionerà con immagini jpg, png e gif? –

6

È necessario utilizzare cv.LoadImageM invece di cv.LoadImage:

In [1]: import cv 
In [2]: import numpy as np 
In [3]: x = cv.LoadImageM('im.tif') 
In [4]: im = np.asarray(x) 
In [5]: im.shape 
Out[5]: (487, 650, 3) 
+0

Grazie mille ... Potresti per favore aiutarmi anche a scoprire che se creo un'immagine usando 'cv.CreateImage (larghezza, altezza, canali)' ... Come può essere convertito in array numpy? – Shan

+0

Penso che sia necessario utilizzare cv.CreateMat o utilizzare cv.CreateMat e copiare dall'immagine sul tappetino utilizzando cv.CvtColor o qualcosa di simile. Dai un'occhiata al link che Paolo ha pubblicato sopra. –

2
def opencv_image_as_array(im): 
    """Interface image from OpenCV's native format to a numpy array. 

    note: this is a slicing trick, and modifying the output array will also change 
    the OpenCV image data. if you want a copy, use .copy() method on the array! 
    """ 
    import numpy as np 
    w, h, n = im.width, im.height, im.channels 
    modes = {1:"L", 3:"RGB"}#, 4:"RGBA"} 
    if n not in modes: 
    raise StandardError('unsupported number of channels: {0}'.format(n)) 
    out = np.asarray(im) if n == 1 else np.asarray(im)[:,:,::-1] ## BGR -> RGB 
    return out 
32

PIL (Python Imaging Library) e Numpy funzionano bene insieme.

Uso le seguenti funzioni.

from PIL import Image 
import numpy as np 

def load_image(infilename) : 
    img = Image.open(infilename) 
    img.load() 
    data = np.asarray(img, dtype="int32") 
    return data 

def save_image(npdata, outfilename) : 
    img = Image.fromarray(np.asarray(np.clip(npdata,0,255), dtype="uint8"), "L") 
    img.save(outfilename) 

Il 'Image.fromarray' è un po 'brutto perché ho clip dati in arrivo a [0255], convertire in byte, quindi creare un'immagine in scala di grigi. Per lo più lavoro in grigio.

immagine An RGB sarebbe qualcosa di simile:

outimg = Image.fromarray(ycc_uint8, "RGB") 
outimg.save("ycc.tif") 
+0

Questo errore con errore, 'TypeError: long() argomento deve essere una stringa o un numero, non 'PixelAccess'' e guardando la documentazione per la classe' PixelAccess' PIL, non sembra offrire metodi che abilitino ' np.array' per convertire i suoi dati sottostanti in un formato 'ndarray'. Devi omettere l'uso di 'img.load()' e trattare solo con il risultato di 'Image.open (...)'. – ely

+0

img.load() funziona attorno a un problema di caching strano in PIL. I dati non verrebbero caricati fino a quando non fosse esplicitamente necessario.L'esempio funziona ancora per me con l'eccezione della modifica di "Importa immagine" in "Immagine di importazione PIL" quando si lavora con Cuscino (la forcella PIL). –

1

Quando si utilizza la risposta di David Poole ho uno SystemError con scala di grigi PNG e forse altri file. La mia soluzione è:

import numpy as np 
from PIL import Image 

img = Image.open(filename) 
try: 
    data = np.asarray(img, dtype='uint8') 
except SystemError: 
    data = np.asarray(img.getdata(), dtype='uint8') 

realtà img.getdata() avrebbe funzionato per tutti i file, ma è più lento, così ho usarlo solo quando l'altro metodo non riesce.

+0

Questo non funziona affatto – mskw

5

Per questo è anche possibile utilizzare matplotlib.

import matplotlib.image as mpimg 

img = mpimg.imread('abc.tiff') 
print(type(img)) 

uscita: <class 'numpy.ndarray'>

+1

Questo è molto semplice. Mi piace :) –

Problemi correlati