简体   繁体   中英

How could I implement image channel drop with the python lib of pillow

I need to randomly zero out 0, 1 or 2 channel of a pillow image. That means I need to randomly set 0, 1 or 2 channels of an image to 0.

How could I do that with pil?

Have you tried using Numpy? It's quite simple.

import numpy as np
import PIL.Image as Image
img = np.array(Image.open("image1.jpg")) # My Image
c = np.random.randint(3, size=1)[0] # Selecting a random channel c
img[:,:,c] = img[:,:,c] * 0 # channel c times 0.

Here's an easy, native PIL way of doing it by multiplying by a transform. I set the default transform so the maths looks like this:

newRed   = 1*oldRed  +  0*oldGreen  +  0*oldBlue  + constant
newGreen = 0*oldRed  +  1*OldGreen  +  0*OldBlue  + constant
newBlue  = 0*oldRed  +  0*OldGreen  +  1*OldBlue  + constant

Then I just change the 1 to 0 where I want a channel zeroed out.

#!/usr/bin/env python3

from PIL import Image

# Open image
im = Image.open('input.png').convert("RGB")

# Pre-set R, G and B multipliers to 1
Rmult, Gmult, Bmult = 1, 1, 1

# Select one (or more) channels to zero out, I choose B channel here
Bmult=0

# Make transform matrix
Matrix = ( Rmult, 0, 0, 0,
           0, Gmult, 0, 0,
           0, 0, Bmult, 0)

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

So, if you start with this:

在此处输入图片说明

and you set the Blue multiplier ( Bmult ) to zero, you'll get:

在此处输入图片说明

If you zero Red and Blue with:

Rmult = Bmult = 0 

you'll get:

在此处输入图片说明

TRY:-

from PIL import Image
import random

# Provide path to your image
img = Image.open(r"Image_Path")

# Converting the Image's mode to RGB, coz you wanted a random channel out of 3 channels
img.convert("RGB")

# Getting individual channels off the image
r, g, b = img.split()

# choice will store a random number b/w 0-2 we will use this value to extract a random channel
choice = random.randrange(0, 3)
null_channel = (r, g, b)[choice]

# printing the index of our randomly selected channel, ( 0 = Red; 1 = Green; 2 = Blue)
print(choice)

# changing each individual pixel value to 0, of our randomly selected channel
null_channel = null_channel.point(lambda p: 0)

# These conditions will provide the null channel to it's original channel's variable
if choice is 1:
    g = null_channel

elif choice is 2:
    b = null_channel

else:
    r = null_channel

# creating a new image with the original two channels' and our null'd channel
new_img = Image.merge("RGB", (r, g, b))

new_img.save("new_img.jpg")

The above code will first convert an image's color mode to RGB, so that we can deal with 3 channels. Then it will extract the individual image channels. Then it will select a random channel of the 3 channel, and convert each pixel value of that channel to (0, 0, 0). Then it will figure out which channel was originally used (R or G or B) and then overwrite the modified values to the channel. In the end, it will create a Image Object by merging all the new channels and saves it.

Sample Image:-

在此处输入图片说明

Image after modification:-

在此处输入图片说明

After analysing the modified Image, we can clearly deduce that the red channel of the image was converted into null channel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM