How to Access and Change Color Channels using PIL?

Pyt*_*_DK 6 python-imaging-library

I'm trying to access the RGB color channels of an image using PIL, and then change the color intensity of the color channel of the entire image at once.

When I say RGB color channels, here is an online example.

I don't understand if this has to be done on a pixel by pixel basis or not.

I image the logic of the code would look like this:

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'))
Run Code Online (Sandbox Code Playgroud)

This answer is the only one that comes close, but it is way too complicated for what I'm trying to do.

I've searched the PIL docs, etc. for a couple of hours but can't seem to get anywhere.

Here's how far I've gotten:

import PIL
from PIL import Image
image=Image.open("my_pic.gif")
image=image.convert('RGB')
display(image.getchannel('R'))
Run Code Online (Sandbox Code Playgroud)

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

我不仅想访问颜色通道值,还想更改它。

Mar*_*ell 13

例如,如果您想将红色通道中的所有像素乘以 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')
Run Code Online (Sandbox Code Playgroud)

请参阅此处的“处理单个波段”


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

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') 
Run Code Online (Sandbox Code Playgroud)

或者,转换为 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') 
Run Code Online (Sandbox Code Playgroud)

这个选项有一个额外的好处,即 Numpy 数组可以与OpenCVscikit-imagevipswand和其他库混合和处理,以完成更复杂的处理 - 形态学、粒度、视频处理、SIFT、对象跟踪......