【问题标题】:Using PIL and NumPy to convert an image to Lab array, modify the values and then convert back使用 PIL 和 NumPy 将图像转换为 Lab 数组,修改值然后转换回来
【发布时间】:2011-03-14 18:57:29
【问题描述】:

我正在尝试使用 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。颜色可以在 SciPy 主干here 中找到。我下载了 color.py 文件以及某些 colordata .txt files。我修改了 color.py 以便它可以独立于 SciPy 源运行,并且所有 似乎 都可以正常工作 - 当我运行转换时,数组中的值会发生变化。

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

出了什么问题?是不是我使用了 color.py 中的函数?

供参考:
源图片 - face-him.jpg
测试所需的所有源文件 - colour-test.zip

【问题讨论】:

  • 您使用的是旧版本的 Scipy 吗?导入颜色一直失败; scipy_base(对我来说不存在)尝试使用的所有函数都是标准的 Numpy 函数(asarrayswapaxes 等)。将color.py的前两行修改为import numpy as sbimport numpy as scipy

标签: python colors numpy python-imaging-library color-space


【解决方案1】:

在没有尝试过的情况下,缩放错误在转换颜色时很常见:
RGB 是字节 0 .. 255,例如黄色 [255,255,0], 而rgb2xyz() 等在浮点数的三倍上工作,黄色 [1.,1.,0]。
color.py 没有范围检查:lab2rgb( rgb2lab([255,255,0]) ) 是垃圾。)

在 IPython 中,%run main.py,然后打印 srcArray 的角并结束?

7 月 13 日添加:记录 / 谷歌,这里有 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()

【讨论】:

  • 谢谢,这条评论对我的问题更有帮助。但是,Nick T 的回答确实帮助我更好地理解了 numpy 的工作方式。
【解决方案2】:

正如 Denis 所指出的,lab2rgbrgb2lab 中没有范围检查,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 中,xyz2lablab2xyz 函数正在做一些我无法一目了然的数学运算(我对 numpy 或图像转换不太熟悉)。

编辑(此代码修复了问题):

PIL 为您提供数字 [0,255],在传递给 rgb2lab 函数之前尝试将它们缩小到 [0,1] 并在出来时备份。例如:

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

【讨论】:

  • 在线c = color.lab2rgb(a)你应该没有做过c = color.lab2rgb(b)吗?因为否则它会尝试将原始的 1,2,3 矩阵从 Lab 转换为 RGB..
  • 再次编辑,为我解决了问题(py 2.6)不确定未来的部门是否适用于旧版本,但必须有一些 numpy 功能。
猜你喜欢
  • 2017-06-25
  • 2017-05-10
  • 1970-01-01
  • 2010-09-27
  • 2019-11-29
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多