Réponses:
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'>
$ pip install opencv-python
pour installer opencv
TypeError: 'mode' is an invalid keyword argument for imread()
mode
argument. Voir ma réponse ci-dessous pour une méthode mise à jour.
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 )
Le 'Image.fromarray' est un peu moche car je découpe les données entrantes à [0,255], je les convertis en octets, puis je crée une image en niveaux de gris. Je travaille principalement en gris.
Une image RVB serait quelque chose comme:
outimg = Image.fromarray( ycc_uint8, "RGB" )
outimg.save( "ycc.tif" )
TypeError: long() argument must be a string or a number, not 'PixelAccess'
et en regardant la documentation de la PixelAccess
classe de PIL , il ne semble pas offrir de méthodes qui permettraient np.array
de convertir ses données sous-jacentes dans un ndarray
format. Vous devez omettre l'utilisation de img.load()
et ne traiter que le résultat de Image.open(...)
.
Vous pouvez également utiliser matplotlib pour cela.
from matplotlib.image import imread
img = imread('abc.tiff')
print(type(img))
production:
<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)
Lorsque j'utilise la réponse de David Poole, j'obtiens une SystemError avec des PNG en échelle 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 c'est plus lent, donc je ne l'utilise que lorsque l'autre méthode échoue.
Le format d'image OpenCV prend en charge l'interface de tableau numpy. Une fonction d'assistance peut être créée pour prendre en charge les images en niveaux de gris ou en couleur. Cela signifie que la conversion BGR -> RVB peut être effectuée de manière pratique avec une tranche numérique et non une copie complète des données d'image.
Remarque: il s'agit d'une astuce, donc la modification du tableau de sortie changera également les données d'image OpenCV. Si vous voulez une copie, utilisez la .copy()
méthode sur le tableau!
import numpy as np
def img_as_array(im):
"""OpenCV's native format to a numpy array view"""
w, h, n = im.width, im.height, im.channels
modes = {1: "L", 3: "RGB", 4: "RGBA"}
if n not in modes:
raise Exception('unsupported number of channels: {0}'.format(n))
out = np.asarray(im)
if n != 1:
out = out[:, :, ::-1] # BGR -> RGB conversion
return out
J'ai également adopté imageio, mais j'ai trouvé les machines suivantes utiles pour le prétraitement et le 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 est que j'utilise numpy pour le traitement d'image, pas seulement pour l'affichage d'image. Dans ce but, les uint8 sont gênants, je les convertis donc en valeurs à virgule flottante allant de 0 à 1.
Lors de la sauvegarde des images, j'ai remarqué que je devais couper moi-même les valeurs hors plage, sinon je me suis retrouvé avec une sortie vraiment grise. (La sortie grise était le résultat de l'imageio compressant la plage complète, qui était en dehors de [0, 256), à des valeurs qui étaient à l'intérieur de la plage.)
Il y avait aussi quelques autres bizarreries, que j'ai mentionnées dans les commentaires.
Vous pouvez facilement obtenir un tableau numpy d'images rgb en utilisant numpy
etImage from PIL
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
im = Image.open('*image_name*') #These two lines
im_arr = np.array(im) #are all you need
plt.imshow(im_arr) #Just to verify that image array has been constructed properly
charger l'image en utilisant la syntaxe suivante: -
from keras.preprocessing import image
X_test=image.load_img('four.png',target_size=(28,28),color_mode="grayscale"); #loading image and then convert it into grayscale and with it's target size
X_test=image.img_to_array(X_test); #convert image into array
cv
s'agit du module OpenCV, vous devez le marquer comme tel. Ce lien peut vous aider: opencv.willowgarage.com/documentation/python/…