J'ai une image RVB. Je veux le convertir en tableau numpy. J'ai fait ce qui suit
im = cv.LoadImage("abc.tiff")
a = numpy.asarray(im)
Il crée un tableau sans forme. Je suppose que c'est un objet iplimage.
Vous pouvez utiliser la nouvelle interface python OpenCV (si je ne me trompe pas, elle est disponible depuis OpenCV 2.2). Il utilise nativement des tableaux numpy:
import cv2
im = cv2.imread("abc.tiff",mode='RGB')
print type(im)
résultat:
<type 'numpy.ndarray'>
PIL (Python Imaging Library) et Numpy fonctionnent bien ensemble.
J'utilise les fonctions suivantes.
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 )
'Image.fromarray' est un peu moche parce que je coupe les données entrantes dans [0,255], les convertit en octets, puis crée une image en niveaux de gris. Je travaille surtout en gris.
Une image RVB serait quelque chose comme:
outimg = Image.fromarray( ycc_uint8, "RGB" )
outimg.save( "ycc.tif" )
Vous pouvez également utiliser matplotlib pour cela.
from matplotlib.image import imread
img = imread('abc.tiff')
print(type(img))
sortie: <class 'numpy.ndarray'>
Vous devez utiliser cv.LoadImageM au lieu de 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)
Réponse tardive, mais j'ai fini par préférer le module imageio
aux autres alternatives
import imageio
im = imageio.imread('abc.tiff')
Semblable à cv2.imread()
, il produit un tableau numpy par défaut, mais sous forme RVB.
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
À partir d’aujourd’hui, votre meilleur choix est d’utiliser:
img = cv2.imread(image_path) # reads an image in the BGR format
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # BGR -> RGB
Vous verrez que img
sera un tableau numpy de type:
<class 'numpy.ndarray'>
En utilisant la réponse de David Poole, j'obtiens un SystemError avec des PNG en niveaux de gris et peut-être d'autres fichiers. Ma solution est:
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' )
En fait, img.getdata () fonctionnerait pour tous les fichiers, mais il est plus lent, je ne l'utilise donc que lorsque l'autre méthode échoue.
J'ai aussi adopté imageio, mais j'ai trouvé les machines suivantes utiles pour le pré et post-traitement:
import imageio
import numpy as np
def imload(*a, **k):
i = imageio.imread(*a, **k)
i = i.transpose((1, 0, 2)) # x and y are mixed up for some reason...
i = np.flip(i, 1) # make coordinate system right-handed!!!!!!
return i/255
def imsave(i, url, *a, **k):
# Original order of arguments was counterintuitive. It should
# read verbally "Save the image to the URL" — not "Save to the
# URL the image."
i = np.flip(i, 1)
i = i.transpose((1, 0, 2))
i *= 255
i = i.round()
i = np.maximum(i, 0)
i = np.minimum(i, 255)
i = np.asarray(i, dtype=np.uint8)
imageio.imwrite(url, i, *a, **k)
La raison en est que j'utilise numpy pour le traitement des images, pas seulement pour l'affichage d'images. Pour cela, les uint8s sont maladroits, je me convertis donc en valeurs à virgule flottante allant de 0 à 1.
Lors de la sauvegarde des images, je me suis rendu compte que je devais réduire moi-même les valeurs hors limites, sinon je me retrouvais avec une sortie très grise. (La sortie grise est le résultat de l’imageio compressant l’ensemble de la plage, située en dehors de [0, 256) en valeurs comprises dans cette plage.)
Il y avait aussi quelques autres bizarreries que j'ai mentionnées dans les commentaires.