【问题标题】:How to generate a mask using Pillow's Image.load() function如何使用 Pillow 的 Image.load() 函数生成蒙版
【发布时间】:2019-11-18 09:25:28
【问题描述】:

我想根据某些像素值创建蒙版。例如:每个像素 B > 200

Image.load() 方法似乎正是我用这些值识别像素所需要的,但我似乎无法弄清楚如何获取所有这些像素并从中创建蒙版图像。

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

【问题讨论】:

标签: python image-processing python-imaging-library image-manipulation


【解决方案1】:

我的意思是让你避免 for 循环,只使用 Numpy。所以,从这张图片开始:

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

如果要使蒙版像素变黑,请使用:

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


您可以针对这样的范围进行更复杂的复合测试:

#!/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')

您也可以对 Reds、Greens 和 Blues 创建条件,然后使用 Numpy 的 np.logical_and()np.logical_or() 来创建复合条件,例如:

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

mask = np.logical_and(bluesHi,redsLo)

【讨论】:

  • 是的,我完全误读了您在另一个问题中的回答。感谢您的澄清!这确实比 for 循环快得多。您将如何扩展以更改多个通道中和某些值之间的像素?例如,每个像素 10 > R > 50 10 > G > 100 50 > B > 200
【解决方案2】:

感谢 Mark Setchell 的回复,我通过制作一个与填充零的图像大小相同的 numpy 数组来解决问题。然后对于 B > 200 的每个像素,我将数组中的相应值设置为 255。最后,我以与输入图像相同的模式将 numpy 数组转换为 PIL 图像。

            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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 2012-12-26
    • 2020-11-06
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多