Python 将大灰度PIL图像转换为黑色和透明

Python 将大灰度PIL图像转换为黑色和透明,python,numpy,python-imaging-library,Python,Numpy,Python Imaging Library,我试图使用一个大的2d阵列来创建一个带有黑色和透明部分的图像遮罩。最初,输入的2d数组是以灰度('L')模式加载的PIL.Image。所以它包含0到255之间的值。现在我想用[0,0,0255](黑色保持黑色)替换所有0,所有值>0都应该是[0,0,0](透明)。我可以这样做: import numpy as np # generate some random test data - normally I just read the input image, which is fast inp

我试图使用一个大的2d阵列来创建一个带有黑色和透明部分的图像遮罩。最初,输入的2d数组是以灰度(
'L'
)模式加载的
PIL.Image
。所以它包含0到255之间的值。现在我想用
[0,0,0255]
(黑色保持黑色)替换所有0,所有值>0都应该是
[0,0,0]
(透明)。我可以这样做:

import numpy as np

# generate some random test data - normally I just read the input image, which is fast
input_data = np.array([np.array([random.choice([0,10]) for x in range(22000)]) for y in range(9000)])

# create a new img containing black and transparent pixels (r,g,b,alpha) and this takes ages
overlay_img = [[[0, 0, 0, 255] if input_data[y][x] == 0 else [0, 0, 0, 0] for x in range(len(input_data[0]))] for y in range(len(input_data))]
overlay_img = np.array(overlay_img)
这需要相当长的时间,因为输入数据太大(~22000x9000)。我很好奇是否有可能更快地做到这一点。我也尝试了
np.where
,但我无法让它工作。也许有办法直接改变PIL图像

仅供参考:最后,我只想使用
imshow
在matplotlib plot的顶部绘制此图像,以便只有相关区域可见(图像透明),其余区域隐藏/黑色

下面是我想做的一个非常简单的例子:
我想您想要这个,但是您还没有显示
imshow()的代码。

在我的MacBook Pro上,最后一行需要800毫秒


如果您需要更高的性能,可以按如下方式使用
numexpr
,所需时间为300毫秒而不是800毫秒:

import random
import numexpr as ne
import numpy as np

# Set up dimensions and random input image
h, w = 9000, 22000
im = np.random.randint(0, 11, (h,w), dtype=np.uint8)

# Create 4-channel mask image
mask = np.zeros((h,w,4), dtype=np.uint8)

# Same but with "numexpr"
mask[...,3] = ne.evaluate("(im==0)*255")

我不明白为什么在前3个通道都为零的情况下需要4通道图像。我也不明白为什么要制作Numpy数组而使用列表理解。请说明您计划如何使用此“遮罩”,以及您希望它产生什么效果。谢谢。关于你的第二个问题:是的,我不需要numpy数组。我只是在示例中使用了它们,因为在我的示例中,输入是一个2d numpy数组,我以前尝试过
numpy.where
。但是如果它在没有numpy阵列的情况下也能工作,那就太棒了!关于你的第一个问题:这就是我为什么写最后一段的原因:我想用imshow来处理这个黑色和透明的图像,这样下面的层要么隐藏起来,要么在最后的图中显示出来。我能想象一个只有一个通道的黑色和透明的图像吗?似乎我们在错误地交流!我建议您不要使用列表理解,而是使用Numpy数组,因为它们更快。我还想看看你想用来显示图像的代码,以及它的外观。谢谢,谢谢!这比我对清单的理解快多了。我怀疑可能有一个快速的解决办法。而且,
mask[…,3]=(im==0)*255确实很整洁。
import random
import numexpr as ne
import numpy as np

# Set up dimensions and random input image
h, w = 9000, 22000
im = np.random.randint(0, 11, (h,w), dtype=np.uint8)

# Create 4-channel mask image
mask = np.zeros((h,w,4), dtype=np.uint8)

# Same but with "numexpr"
mask[...,3] = ne.evaluate("(im==0)*255")