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

时间:2020-07-13 12:17:51

标签: python numpy python-imaging-library

我正在尝试使用大型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图上绘制该图像,这样就只有可见的相关区域(图像是透明的),其余的区域是隐藏的/黑色。

这里只是我想做的非常简单的小例子: enter image description here

1 个答案:

答案 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")
相关问题