Я делаю некоторую обработку изображений в Python с помощью PIL, я должен извлечь слой яркости из ряда изображений, и сделать некоторую обработку на том использовании numpy, затем отложить отредактированный слой яркости в изображение и сохранить его. Проблема, я, может казаться, не получаю значимого представления своего Изображения в формате YCbCr, или по крайней мере я не понимаю то, что PIL дает мне в YCbCr. Документация PIL утверждает, что формат YCbCr дает три канала, но когда я захватываю данные из изображения с помощью np.asarray, я получаю 4 канала. Хорошо, таким образом, я полагаю, что нужно быть альфой.
Вот некоторый код, который я использую для тестирования этого процесса:
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")
Я ожидаю полутоновую версию своего изображения, но что я получаю, это смешало путаницу:
Кто-либо может объяснить мне, где я иду не так, как надо? Тот же код в matlab работает точно, как я ожидаю.
Поскольку YCbCr - это простое, математически детерминированное преобразование из цветового пространства RGB, прохождение через промежуточный этап YCbCr - это просто косвенный способ извлечения вычисленного (не абсолютного) значения яркости из изображения. Того же самого можно добиться более прямым способом:
yIm = pengIm.convert('L')
Я подозреваю, что проблема с преобразованием через numpy asarray или fromarray или в коде numpy, потому что последовательность:
>>> 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
Все работает как ожидалось. Кстати,
>>> 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')
Дает мне три канала, а не четыре.