我正在尝试使用大型2D阵列创建具有黑色和透明部分的图像蒙版。最初,输入2d数组是一个PIL.Image
,它以灰度('L'
)模式加载。因此它包含0到255之间的值。现在我想用[0,0,0,255]
替换所有0(黑色保持黑色),并且所有> 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图像?
fyi:最后,我只想用imshow
在我的matplotlib图上绘制该图像,这样就只有可见的相关区域(图像是透明的),其余的区域是隐藏的/黑色。
答案 0 :(得分:1)
我认为您想要这样做,但是您没有显示imshow()
的代码:
#!/usr/bin/env python3
import random
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)
mask[...,3] = (im==0) * 255
最后一行在MacBook Pro上花费800毫秒。
如果需要更高的性能,可以按以下方式使用numexpr
,所需时间为300ms而不是800ms:
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")