我有一个 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。
我觉得我肯定缺少一些基本的东西......
请您参考如下方法:
问题出在以下行:
plt.imsave(r"../img/sim.png", img, vmin=0, vmax=2**12, cmap='viridis')
当您使用 cmap='viridis'
指定颜色图时,它会将您的图像量化为 8 位,因此它可以在 PNG 图像和 boom 中使用 256 色调色板(最大可能) !您的 16 位数据已损坏(丢失)。
如果您使用 imageio
它可以保存 16 位数据,因此您可以将上面的行替换为:
import imageio
...
imageio.imwrite('12-bit.png',img)
这将保留您的 16 位数据。一个潜在的问题是数据现在是灰度的并且很难看到。这可能不是问题,因为您保存数据可能只是为了存储它而不是为了可视化它。我猜你会有两个选择:
将文件存储两次(磁盘很便宜)- 一次以灰度存储,一次以 viridis 颜色图进行可视化,或者,
只需在灰度中存储一次,并制作一个“查看器”工具来加载灰度并使用 viridis 调色板渲染它。