Python Imaging: problemas YCbCr

Estoy procesando algunas imágenes en Python usando PIL, necesito extraer la capa de luminancia de una serie de imágenes, y hacer un procesamiento de eso usando numpy, luego volver a colocar la capa de luminancia editada en la imagen y guardarla. El problema es que parece que no puedo obtener una representación significativa de mi imagen en un formato YCbCr, o al menos no entiendo qué me está dando PIL en YCbCr. La documentación de PIL afirma que el formato YCbCr da tres canales, pero cuando tomo los datos de la imagen usando np.asarray, obtengo 4 canales. Ok, así que me imagino que uno debe ser alfa.

Aquí hay un código que estoy usando para probar este proceso:

import Image as im import numpy as np pengIm = im.open("Data\\Test\\Penguins.bmp") yIm = pengIm.convert("YCbCr") testIm = np.asarray(yIm) grey = testIm[:,:,0] grey = grey.astype('uint8') greyIm = im.fromarray(grey, "L") greyIm.save("Data\\Test\\grey.bmp") 

Estoy esperando una versión en escala de grises de mi imagen, pero lo que obtengo es este lío desordenado:

http://sofes.miximages.com/python/zlhIh.png

¿Alguien puede explicarme dónde me voy mal? El mismo código en matlab funciona exactamente como lo esperaba.

Related of "Python Imaging: problemas YCbCr"

Dado que YCbCr es una conversión simple y matemáticamente determinada del espacio de color RGB, pasar por la etapa intermedia de YCbCr es solo una forma indirecta de extraer un valor de luminancia calculado (no absoluto) de una imagen. Puedes lograr lo mismo, más directamente con:

 yIm = pengIm.convert('L') 

Sospecho que hay un problema con su conversión a través de una matriz de nómadas o de una matriz o en su código de numpy porque la secuencia:

 >>> import Image >>> import ImageOps >>> import ImageChops >>> c = Image.open('squished_levels.png') >>> c  >>> c.getbands() ('R', 'G', 'B') >>> d = c.convert('L') >>> d.getextrema() # squished_levels.png has squished levels for testing (77, 182) >>> d.getbands() ('L',) >>> e = ImageOps.equalize(d) >>> e.getextrema() (0, 255) >>> f = e.convert('RGB') >>> g = ImageChops.lighter(c, f) >>> g.show() # not squished in luminance 

Todo funciona como se espera. De paso,

 >>> h = c.convert('YCbCr') >>> h  >>> h.getpixel((0,0)) (119, 127, 128) >>> h.getbands() ('Y', 'Cb', 'Cr') 

Me da tres canales, no cuatro.

Si convierte la imagen a una matriz numpy como esta, el problema debería resolverse:

 ycbcr_array = numpy.ndarray((pengIm.size[1], pengIm.size[0], 3), 'u1', yIm.tostring()) 

Lo encontré aquí .