我有一个12位相机,它以数组的形式拍摄图像(值是整数)。当我通过matplotlib将数组另存为.png,然后将其读回时,值在RGBA中(与预期一样)。通过阅读.png,我需要能够将其转换回其原始整数值。
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
# simulate some data
x = np.arange(0,100.1,1)
y1 = norm.pdf(x, loc=50, scale=20)
y2 = norm.pdf(x, loc=40, scale=10)
scaler = 1024/np.max(np.outer(y1,y2)) # img is 12 bits
img = np.outer(y1,y2)*scaler
img = img.astype(np.uint16) # force to be 16 bit as there is no 12 bit in np
print(np.max(img), np.min(img), img.shape)
plt.imshow(img)
plt.show()
plt.imsave(r"../img/sim.png", img, vmin=0, vmax=2**12, cmap='viridis')
img2 = plt.imread(r"../img/sim.png")
img2 # can we convert these RGBA values back to the original integers?
我不知道如何将这些(有效地)转换回原始整数。我相信这是可能的,因为我读过.png使用无损压缩。基本上,我需要确定img2等于img。
我觉得我肯定在这里缺少一些基本的东西...
答案 0 :(得分:1)
问题出在以下几行:
plt.imsave(r"../img/sim.png", img, vmin=0, vmax=2**12, cmap='viridis')
当您使用cmap='viridis'
指定色彩图时,它会将您的图片量化为8位,这样它就可以在PNG图片中使用256色调色板(最大可能)!您的16位数据是吐司(丢失)。
如果使用imageio
,则可以保存16位数据,因此您可以将上面的行替换为:
import imageio
...
imageio.imwrite('12-bit.png',img)
这将保留您的16位数据。一个潜在的问题是数据现在是灰度的,很难看到。这可能不是问题,因为您可能只是为了存储数据而不是对其进行可视化而保存了数据。我想您会有两个选择:
要么将文件存储两次(磁盘便宜)-一次以灰度存储用于存储,一次使用viridis颜色图进行可视化,或者
只需在灰度中存储一次,然后制作一个“查看器” 工具即可加载灰度并使用viridis调色板进行渲染。