【问题标题】:How to Access and Change Color Channels using PIL?如何使用 PIL 访问和更改颜色通道?
【发布时间】:2020-04-26 16:38:08
【问题描述】:

我正在尝试使用PIL 访问图像的 RGB 颜色通道,然后一次更改整个图像的颜色通道的颜色强度。

当我说 RGB 颜色通道时,here 是一个在线示例。

我不明白这是否必须逐个像素地完成。

我认为代码的逻辑如下所示:

import PIL
from PIL import Image
image=Image.open("my_pic.gif")
image=image.convert('RGB')
# made up function
channel_values = image.get_channel_values()
#channel_values = i.e. (50, 100, 50)
# do some math function to transform channel_values
channel_values = (95,125,75)
image.update_channel_value('R',channel_values)
display(image.getchannel('R'))

This 答案是唯一接近的答案,但对于我想要做的事情来说太复杂了。

我已经搜索了几个小时的 PIL 文档等,但似乎找不到任何地方。

这是我已经走了多远:

import PIL
from PIL import Image
image=Image.open("my_pic.gif")
image=image.convert('RGB')
display(image.getchannel('R'))

问题是image.getchannel() 只返回一个灰色/黑白图像。

我不仅想访问颜色通道值,我也想改变它。

【问题讨论】:

  • 您能否进一步详细说明“改变强度”是什么意思?你究竟想做什么?处理单个像素?一次处理所有像素?
  • @HansHirse,根据您的要求澄清了 Q。这是针对整个图像/所有像素,而不仅仅是单个像素。
  • 现在还不清楚,你想怎么改变强度。你想增值2吗?你想添加一些“模式”吗?剪裁需要注意吗?也许,只需添加一些示例输入图像和所需的输出。
  • @HansHirse 根据您的反馈再次更新了 Q,感谢您帮助我提出更好的问题。
  • 如果你的图片是 20px 宽和 10px 高,它将有 200 像素,即 20x10。每个像素都有一个红色、一个绿色和一个蓝色值。所以你将有 200 个红色值、200 个绿色值和 200 个蓝色值。如果将所有红色值乘以 1.1,红色将在图像中突出 10%。如果你将所有的绿色值乘以 0.8,所有的绿色将不那么突出 20%。你想做什么样的事情?

标签: python-imaging-library


【解决方案1】:

例如,如果您想将红色通道中的所有像素乘以 1.2,将所有绿色像素乘以 0.9,您有多种选择....


将图像拆分为红色、绿色和蓝色通道,放大红色通道并重新组合:

from PIL import Image
im = Image.open('image.jpg').convert('RGB')

# Split into 3 channels
r, g, b = im.split()

# Increase Reds
r = r.point(lambda i: i * 1.2)

# Decrease Greens
g = g.point(lambda i: i * 0.9)

# Recombine back to RGB image
result = Image.merge('RGB', (r, g, b))

result.save('result.png')

请参阅“处理单个频段”here


或者,使用矩阵来转换通道:

from PIL import Image 

# Open image 
im = Image.open('image.jpg') 

# Make transform matrix, to multiply R by 1.1, G by 0.9 and leave B unchanged
# newRed   = 1.1*oldRed  +  0*oldGreen    +  0*oldBlue  + constant
# newGreen = 0*oldRed    +  0.9*OldGreen  +  0*OldBlue  + constant
# newBlue  = 0*oldRed    +  0*OldGreen    +  1*OldBlue  + constant
Matrix = ( 1.1,   0,  0, 0, 
           0,   0.9,  0, 0, 
           0,     0,  1, 0) 

# Apply transform and save 
im = im.convert("RGB", Matrix) 
im.save('result.png') 

或者,转换为 Numpy 数组,进行一些处理并转换回 PIL Image:

from PIL import Image 

# Open image 
im = Image.open('image.jpg') 

# Make into Numpy array of floats
na = np.array(im).astype(np.float)

# Multiply all red values by 1.1
na[...,0] *= 1.1

# Reduce green values
na[...,1] *= 0.9

# You may want to use "np.clip()" here to ensure you don't exceed 255

# Convert Numpy array back to PIL Image and save
pi = Image.fromarray(na.astype(np.uint8))
pi.save('result.png') 

此选项的额外好处是 Numpy 数组可以与 OpenCVscikit-imagevips 混合和处理>wand 和其他库来完成更复杂的处理 - 形态、粒度、视频处理、SIFT、对象跟踪...

【讨论】:

    猜你喜欢
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 2019-09-05
    • 1970-01-01
    • 2018-06-29
    • 2016-07-27
    相关资源
    最近更新 更多