Python Imaging: problems with YCbCr

I am involved in image processing in Python using PIL, I need to extract the brightness layer from a series of images and do some processing using numpy, and then return the edited brightness layer to the image and save it. The problem is that I cannot imagine any meaningful representation of my image in YCbCr format, or at least I don’t understand what PIL gives me in YCbCr. The PIL documentation claims that the YCbCr format provides three channels, but when I extract data from the image using np.asarray, I get 4 channels. Ok, so I think you need to be alpha.

Here is the code I use to test this process:

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

I am expecting a grayscale version of the image, but what I get is a messy mess:

http://i.imgur.com/zlhIh.png

Can someone explain to me where I'm wrong? The same code in matlab works exactly as I expect.

+4
source share
2 answers

Since YCbCr is a simple , mathematically determined conversion from the RGB color space, passing through the intermediate stage of YCbCr is just an indirect way to derive the calculated (not absolute) brightness value from the image. You can accomplish the same thing more directly with:

 yIm = pengIm.convert('L') 

I suspect there is a problem with converting via numpy asarray or fromarray or to your numpy code, because the sequence is:

 >>> import Image >>> import ImageOps >>> import ImageChops >>> c = Image.open('squished_levels.png') >>> c <PngImagePlugin.PngImageFile image mode=RGB size=320x240 at 0xB7686DAC> >>> 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 

Everything works as expected. By the way

 >>> h = c.convert('YCbCr') >>> h <Image.Image image mode=YCbCr size=320x240 at 0xB761378C> >>> h.getpixel((0,0)) (119, 127, 128) >>> h.getbands() ('Y', 'Cb', 'Cr') 

Gives me three channels, not four.

+4
source

If you convert the image to a numpy array like this, the problem should be solved:

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

I found here .

0
source

Source: https://habr.com/ru/post/1309243/


All Articles