How to Access and Change Color Channels using PIL?

前端 未结 1 1116
野趣味
野趣味 2020-12-19 14:52

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.

相关标签:
1条回答
  • 2020-12-19 15:34

    If, for example, you want to multiply all pixels in the red channel by 1.2, and all the green pixels by 0.9, you have several options....


    Split the image into Red, Green and Blue channels, upscale the Red channel and recombine:

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

    See "Processing Individual Bands" here.


    Or, use a matrix to transform the channels:

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

    Or, convert to Numpy array, do some processing and convert back to 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') 
    

    This option has the added benefit that the Numpy arrays can be intermixed and processed with OpenCV, scikit-image, vips, wand and other libraries to get MUCH more sophisticated processing done - morphology, granulometry, video processing, SIFT, object tracking...

    0 讨论(0)
提交回复
热议问题