Используя PIL и NumPy, чтобы преобразовать изображение в массив Lab, измените значения, а затем выполните обратное
Я пытаюсь преобразовать изображение PIL в массив, используя NumPy. Затем я хочу преобразовать этот массив в значения Lab, изменить значения, а затем преобразовать массив обратно в изображение и сохранить изображение. У меня есть следующий код:
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")
Этот код зависит от PIL, NumPy и цвета. цвет можно найти в тубе SciPy здесь. Я загрузил файл color.py вместе с некоторыми colordata.txt файлами. Я изменил color.py так, чтобы он мог запускаться независимо от источника SciPy, и все кажется, что он работает нормально - значения в массиве меняются при выполнении преобразований.
Моя проблема в том, что когда я запускаю приведенный выше код, который просто преобразует изображение в Lab, а затем обратно в RGB и сохраняет его, я возвращаю следующее изображение:
![alt text]()
Что происходит не так? Является ли это тем, что я использую функции color.py?
Для справки:
Изображение источника - face-him.jpg
Все исходные файлы, необходимые для тестирования - colour-test.zip
Ответы
Ответ 1
Не пробовав, ошибки масштабирования распространены при преобразовании цветов:
RGB - это байты 0.. 255, например. желтый [255,255,0],
тогда как rgb2xyz()
и т.д. работают на тройках поплавков, желтый [1., 1., 0].
(color.py
не имеет проверок диапазона: lab2rgb( rgb2lab([255,255,0]) )
является нежелательным.)
В IPython, %run main.py
, затем печатайте углы srcArray и заканчиваете?
Добавлено 13July: для записи/для google, вот идиомы NumPy для упаковки, распаковки и преобразования массивов изображений 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()
Ответ 2
Как отметил Денис, в lab2rgb
или rgb2lab
нет проверок диапазона, а rgb2lab
ожидает ожидаемых значений в диапазоне [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]])
В color.py функции xyz2lab
и lab2xyz
выполняют некоторую математику, которую я не могу вывести с первого взгляда (я не знаком с преобразованиями numpy или изображений).
Изменить (этот код исправляет проблему):
PIL дает вам номера [0,255], попробуйте масштабировать их до [0,1], прежде чем перейти к функции rgb2lab и выполнить резервное копирование при выходе. например:.
#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)