python - procesamiento - Usando PIL y NumPy para convertir una imagen a Lab array, modifique los valores y luego conviértalo de nuevo
librerias para procesamiento de imagenes en python (2)
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. funcionan 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 imprime esquinas de srcArray y termina?
Agregado el 13 de julio: para el registro / para google, aquí están los modismos de NumPy para empacar, descomprimir y convertir matrices de imágenes RGB:
# 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()
Estoy tratando de convertir una imagen PIL en una matriz usando NumPy. Luego quiero convertir esa matriz en valores Lab, modificar los valores y luego convertir la matriz nuevamente 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 SciPy aquí . Descargué el archivo color.py junto con ciertos archivos colordata .txt . Modifiqué color.py para que pueda ejecutarse independientemente de la fuente SciPy y todo parece funcionar bien: los valores en la matriz cambian cuando ejecuto las conversiones.
Mi problema es que cuando ejecuto el código anterior que simplemente convierte una imagen en Lab, luego de vuelta a RGB y la guarda, me devuelve la siguiente imagen:
¿Qué está pasando mal? ¿Es el hecho de que estoy usando las funciones de color.py?
Para referencia:
Fuente de la imagen - face-him.jpg
Todos los archivos fuente requeridos para probar - colour-test.zip
Como señaló Denis, no hay controles de rango en lab2rgb
o rgb2lab
, y parece que rgb2lab
espera 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 algunas lab2xyz
matemáticas que no puedo deducir de un vistazo (no estoy tan familiarizado con las transformaciones numpy o de imagen).
Editar (este código corrige el problema):
PIL te da los números [0,255], intenta escalarlos a [0,1] antes de pasar a la función rgb2lab y hacer una copia de seguridad al salir. 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)