How to generate a mask using Pillow's Image.load() function

可紊 提交于 2019-12-11 02:56:38

问题


I want to create a mask based on certain pixel values. For example: every pixel where B > 200

The Image.load() method seems to be exactly what I need for identifying the pixels with these values, but I can't seem to figure out how to take all these pixels and create a mask image out of them.

            R, G, B = 0, 1, 2

            pixels = self.input_image.get_value().load()
            width, height = self.input_image.get_value().size

            for y in range(0, height):
                for x in range(0, width):
                    if pixels[x, y][B] > 200:
                        print("%s - %s's blue is more than 200" % (x, y))
``

回答1:


I meant for you to avoid for loops and just use Numpy. So, starting with this image:

from PIL import Image
import numpy as np

# Open image
im = Image.open('colorwheel.png')

# Make Numpy array
ni = np.array(im)

# Mask pixels where Blue > 200
blues = ni[:,:,2]>200

# Save logical mask as PNG
Image.fromarray((blues*255).astype(np.uint8)).save('result.png')

If you want to make the masked pixels black, use:

ni[blues] = 0
Image.fromarray(ni).save('result.png')


You can make more complex, compound tests against ranges like this:

#!/usr/bin/env python3

from PIL import Image
import numpy as np

# Open image
im = Image.open('colorwheel.png')

# Make Numpy array
ni = np.array(im)

# Mask pixels where 100 < Blue < 200
blues = ( ni[:,:,2]>100 ) & (ni[:,:,2]<200)

# Save logical mask as PNG
Image.fromarray((blues*255).astype(np.uint8)).save('result.png')

You can also make a condition on Reds, Greens and Blues and then use Numpy's np.logical_and() and np.logical_or() to make compound conditions, e.g.:

bluesHi = ni[:,:,2] > 200 
redsLo  = ni[:,:,0] < 50

mask = np.logical_and(bluesHi,redsLo)



回答2:


Thanks to the reply from Mark Setchell, I solved by making a numpy array the same size as my image filled with zeroes. Then for every pixel where B > 200, I set the corresponding value in the array to 255. Finally I converted the numpy array to a PIL image in the same mode as my input image was.

            R, G, B = 0, 1, 2

            pixels = self.input_image.get_value().load()
            width, height = self.input_image.get_value().size
            mode = self.input_image.get_value().mode

            mask = np.zeros((height, width))

            for y in range(0, height):
                for x in range(0, width):
                    if pixels[x, y][2] > 200:
                        mask[y][x] = 255

            mask_image = Image.fromarray(mask).convert(mode)


来源:https://stackoverflow.com/questions/56942102/how-to-generate-a-mask-using-pillows-image-load-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!