嗨,我是python的新手,我正在尝试将2d numpy数组保存到png文件中。
我的2d numpy数组中的每个元素都是0到100之间的整数,并且我有一个getColor()
函数将其映射为rgb值。我现在的工作方式是构造一个3通道numpy数组,其形状与2d numpy数组相同,然后将每个值映射到相应的rgb值。但是,这要花费很多时间,我觉得应该有一个更有效的方法。我的代码目前需要大约5秒钟来处理一张图像。
import numpy as np
import imageio
flt_m = get2dArray() # returns a (880*880) numpy array
def getColor(value):
if(value < 0):
return (0,0,0)
elif(value < 50):
return (100,150,200)
else:
return (255,255,255)
canvas = np.zeros((flt_m.shape[0], flt_m.shape[1], 3)).astype(np.uint8)
for row in range(flt_m.shape[0]):
for col in range(flt_m.shape[1]):
rgb = getColor(flt_m[row, col])
for i in range(3):
canvas[row, col, i] = rgb[i]
imageio.imwrite('test.png', canvas) # saves file to png
答案 0 :(得分:4)
您可以使用boolean indexing on numpy arrays设置数组的不同子集。
所以也许您使用:
canvas = np.ones([880, 880, 3], dtype=np.uint8) * 255 # initialize the whole RGB-Array with (255, 255, 255)
canvas[flt_m<50] = (100, 150, 200) # set all values where flt_m is <50 to (100, 150, 200)
但是,如果flt_m
中确实有负值,您仍然可以添加
canvas[flt_m<0] = (0, 0, 0)
答案 1 :(得分:3)
您已经有了@SpghttCd的答案的很好的解决方案,但是您的写入时间似乎很慢,所以我考虑了另一种解决方案...
由于图像中只有2-3种颜色,因此您可以编写一个已着色的图像(最多支持256种颜色),并且应该占用更少的内存,更少的处理和更少的磁盘空间。而不是为每个像素存储3个字节(红色为1个,绿色为1个,蓝色为1个),而是在每个像素处存储一个字节,该字节是256色RGB查找表或调色板的索引。
import numpy as np
from PIL import Image
# Generate synthetic image of same size with random numbers under 256
flt_im = np.random.randint(0,256,(880,880), dtype=np.uint8)
# Make numpy array into image without allocating any more memory
p = Image.fromarray(flt_im, mode='L')
# Create a palette with 256 colours - first 50 are your blueish colour, rest are white
palette = 50*[100,150,200] + 206*[255,255,255]
# Put palette into image and save
p.putpalette(palette)
p.save('result.png')
很明显,我无法检查您计算机上的性能,但是如果将我的脸蛋版本与SpghttCd的版本进行比较,我会发现50倍的速度差异:
def SpghttCd(flt_im):
canvas = np.ones([880, 880, 3], dtype=np.uint8) * 255
canvas[flt_im<50] = (100, 150, 200)
imageio.imwrite('SpghttCd.png', canvas)
def me(flt_im):
# Make numpy array into image without allocating any more memory
p = Image.fromarray(flt_im, mode='L')
# Create a palette with 256 colours - first 50 are your blueish colour, rest are white
palette = 50*[100,150,200] + 206*[255,255,255]
# Put palette into image and save
p.putpalette(palette)
p.save('result.png')
# Generate random data to test with - same for both
flt_im = np.random.randint(0,256,(880,880), dtype=np.uint8)
%timeit me(flt_im)
In [34]: %timeit me(flt_im)
34.1 ms ± 1.06 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [37]: %timeit SpghttCd(flt_im)
1.68 s ± 7.17 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
我注意到,从PNG更改为GIF(对于这种类型的事物也是如此)可将速度进一步提高7倍,即从5ms变为34ms。