Python 使用PIL和NumPy将图像转换为Lab array,修改值,然后再转换回

Python 使用PIL和NumPy将图像转换为Lab array,修改值,然后再转换回,python,colors,numpy,python-imaging-library,color-space,Python,Colors,Numpy,Python Imaging Library,Color Space,我正在尝试使用NumPy将PIL图像转换为数组。然后我想将该数组转换为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 nu

我正在尝试使用NumPy将PIL图像转换为数组。然后我想将该数组转换为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和颜色。颜色可以在松软的树干上找到。我下载了color.py文件和某些文件。我修改了color.py,这样它就可以独立于SciPy源代码运行,而且似乎一切都很好——当我运行转换时,数组中的值会发生变化

我的问题是,当我运行上面的代码时,只需将图像转换为Lab,然后返回到RGB并保存它,我就会返回以下图像:

出什么事了?我使用的是color.py中的函数吗

供参考:
源图像-

测试所需的所有源文件-

正如Denis指出的,在
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会给你[0255]个数字,在传递到rgb2lab函数之前,尝试将这些数字缩小到[0,1],并在出来时进行备份。e、 g:

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

未经尝试,转换颜色时缩放错误很常见:
RGB是字节0。。255,例如黄色[255255,0], 而
rgb2xyz()
等处理三个浮点数,黄色[1,1,0]。
color.py
没有范围检查:
lab2rgb(rgb2lab([255255,0]))
是垃圾。)

在IPython中,
%运行main.py
,然后打印srcArray的角点并结束

7月13日添加:为了记录/为了谷歌,这里有一些打包、解包和转换RGB图像阵列的NumPy习惯用法:

    # 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()
#解包图像阵列,10x5x3->rgb--
img=np.arange(10*5*3)。重塑((10,5,3))
打印“img.shape:”,img.shape
r、 g,b=img.转置(2,0,1)#3 10 5
打印“r.shape:”,r.shape
#再次包装10 x 5 r g b->10 x 5 x 3--
rgb=np.数组((r,g,b)).再次转置(1,2,0)#10 5 3
打印“rgb.shape:”,rgb.shape
断言(rgb==img).all()
#rgb 0。。255浮点0。。1 --
imgfloat=img.astype(np.float32)/255。
img8=(imgfloat*255).round().astype(np.uint8)
断言(img==img8).all()

您使用的是旧版本的Scipy吗?导入颜色一直失败;scipy_base(我不存在)尝试使用的所有函数都是标准的Numpy函数(
asarray
swapax
,等等)。在
c=color.lab2rgb(a)
行上,将color.py的前两行修改为
import numpy as sb
import numpy as scipy
?因为它正试图将原始的1,2,3矩阵从实验室转换为RGB..再次编辑,问题为我解决(py 2.6)不确定未来的除法是否适用于旧版本,但必须有一些numpy函数来完成。谢谢,此注释对我的问题更有帮助。然而,Nick T的回答确实帮助我更好地理解了numpy的工作方式。