En utilisant PIL et NumPy pour convertir une image en Lab array, modifier les valeurs et ensuite convertir retour

j'essaie de convertir une image PIL en un tableau en utilisant NumPy. Je veux alors convertir ce tableau en valeurs Lab, modifier les valeurs et ensuite convertir le tableau de nouveau dans une image et sauver l'image. J'ai le code suivant:

import Image, color, numpy

# Open the image file
src = Image.open("face-him.jpg")

# Attempt to ensure image is RGB
src = src.convert(mode="RGB")

# Create array of image using numpy
srcArray = numpy.asarray(src)

# Convert array from RGB into Lab
srcArray = color.rgb2lab(srcArray)

# Modify array here

# Convert array back into Lab
end = color.lab2rgb(srcArray)

# Create image from array
final = Image.fromarray(end, "RGB")

# Save
final.save("out.jpg")

ce code dépend de PIL, NumPy et couleur . la couleur peut être trouvée dans le tronc SciPy ici . J'ai téléchargé color.py dossier avec certains colordata .fichiers txt . J'ai modifié le color.py de sorte qu'il peut fonctionner indépendamment de la source de SciPy et il tout semble pour travailler des valeurs fines dans le tableau sont changées lorsque j'exécute des conversions.

mon problème est que lorsque j'exécute le code ci-dessus qui convertit simplement une image en Lab, puis la renvoie à RGB et la sauvegarde, je récupère l'image suivante:

alt text

Qu'est-ce qui ne va pas? Être c'est le fait que j'utilise les fonctions de color.py Je ne sais pas.

pour référence:

Source de l'Image - en face de lui.jpg

Tous les fichiers sources nécessaires pour tester - test de couleur .zip

14
demandé sur betamax 2010-07-12 16:10:02

2 réponses

sans l'avoir essayé, les erreurs d'échelle sont fréquentes dans la conversion des couleurs:

RGB est de 0 .. 255, p.ex. jaune [255,255,0], alors que rgb2xyz() etc. travail sur des triples de flotteurs, Jaune [1.,1.,0].

( color.py n'a pas de contrôle de portée: lab2rgb( rgb2lab([255,255,0]) ) est une camelote.)

à IPython, %run main.py , puis imprimer les coins de srcArray et terminer ?

ajouté le 13 juillet: pour rappel / pour google, voici NumPy idiomes à emballer, déballer et de les convertir RVB de l'image des tableaux:

    # unpack image array, 10 x 5 x 3 -> r g b --
img = np.arange( 10*5*3 ).reshape(( 10,5,3 ))
print "img.shape:", img.shape
r,g,b = img.transpose( 2,0,1 )  # 3 10 5
print "r.shape:", r.shape

    # pack 10 x 5 r g b -> 10 x 5 x 3 again --
rgb = np.array(( r, g, b )).transpose( 1,2,0 )  # 10 5 3 again
print "rgb.shape:", rgb.shape
assert (rgb == img).all()

    # rgb 0 .. 255 <-> float 0 .. 1 --
imgfloat = img.astype(np.float32) / 255.
img8 = (imgfloat * 255).round().astype(np.uint8)  
assert (img == img8).all()
10
répondu denis 2010-07-13 10:46:30

comme Denis L'a souligné, il n'y a pas de vérification de la plage dans lab2rgb ou rgb2lab , et rgb2lab semble s'attendre à des valeurs dans la plage [0,1].

>>> a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> color.lab2rgb(color.rgb2lab(a))
array([[ -1.74361805e-01,   1.39592186e-03,   1.24595808e-01],
       [  1.18478213e+00,   1.15700655e+00,   1.13767806e+00],
       [  2.62956273e+00,   2.38687422e+00,   2.21535897e+00]])
>>> from __future__ import division
>>> b = a/10
>>> b
array([[ 0.1,  0.2,  0.3],
       [ 0.4,  0.5,  0.6],
       [ 0.7,  0.8,  0.9]])
>>> color.lab2rgb(color.rgb2lab(a))
array([[ 0.1,  0.2,  0.3],
       [ 0.4,  0.5,  0.6],
       [ 0.7,  0.8,  0.9]])

In color.py, les fonctions xyz2lab et lab2xyz font des calculs que je ne peux pas déduire d'un coup d'oeil (Je ne suis pas si familier avec les transformations de num PY ou d'image).

Edit (ce code corrige le problème):

PIL vous donne des nombres [0.255], essayez réduire ceux-ci à [0,1] avant de passer à la fonction rgb2lab et de revenir en haut lors de la sortie. par exemple:

#from __future__ import division # (if required)
[...]
# Create array of image using numpy
srcArray = numpy.asarray(src)/255

# Convert array from RGB into Lab
srcArray = color.rgb2lab(srcArray)

# Convert array back into Lab
end = color.lab2rgb(srcArray)*255
end = end.astype(numpy.uint8)
6
répondu Nick T 2010-07-14 21:33:50