Uso de PIL y NumPy para convertir una imagen a Lab array, modificar los valores y luego volver a convertir

Estoy tratando de convertir una imagen PIL en una matriz usando NumPy. Luego quiero convertir esa matriz en valores de laboratorio, modificar los valores y luego volver a convertir la matriz en una imagen y guardar la imagen. Tengo el siguiente código:

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

Este código depende de PIL, NumPy y color . El color se puede encontrar en el tronco de SciPy aquí . Descargué el archivo color.py junto con ciertos archivos .txt de colordata . Modifiqué el color.py para que pueda ejecutarse independientemente de la fuente SciPy y todo parece funcionar bien: los valores de la matriz se modifican cuando ejecuto las conversiones.

Mi problema es que cuando ejecuto el código anterior que simplemente convierte una imagen a Lab, luego a RGB y la guarda, obtengo la siguiente imagen:

texto alternativo

¿Qué va mal? ¿Es el hecho de que estoy usando las funciones de color.py?

Para referencia:
Fuente de imagen – face-him.jpg
Todos los archivos de origen necesarios para probar – colour-test.zip

Sin haberlo probado, los errores de escala son comunes en la conversión de colores:
RGB es bytes 0 .. 255, por ejemplo, amarillo [255,255,0], mientras que rgb2xyz() etc. trabaja en triples de flotadores, amarillo [1., 1., 0].
( color.py no tiene controles de rango: lab2rgb( rgb2lab([255,255,0]) ) es basura).

En IPython, %run main.py , luego imprima las esquinas de srcArray y finalice?

Agregado el 13 de julio: para el registro / para google, aquí están los modismos NumPy para empaquetar, descomprimir y convertir matrices de imágenes RGB:

  # unpack image array, 10 x 5 x 3 -> rgb -- 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 rgb -> 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() 

Como Denis señaló, no hay controles de rango en lab2rgb o rgb2lab , y rgb2lab parece esperar valores en el rango [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]]) 

En color.py, las funciones xyz2lab y lab2xyz están haciendo algunos cálculos matemáticos que no puedo deducir de un vistazo (no estoy familiarizado con las transformaciones de imágenes o de números).

Editar (este código soluciona el problema):

PIL le da números [0,255], intente reducirlos a [0,1] antes de pasar a la función rgb2lab y haga una copia de seguridad cuando salga. p.ej:

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