当使用 Scipy 保存二维 Numpy 数组(单个值)toimage
或imsave
像素值与 Numpy 数组中的值不完全匹配时。相反,有一些区域,主要是在边缘,图像算法似乎使用了某种插值。
是否有一个选项可以停止插值并保留确切的数据(例如 7 总是在 PNG 中获取 rgb(7,7,7)?
当使用 Scipy 保存二维 Numpy 数组(单个值)toimage
或imsave
像素值与 Numpy 数组中的值不完全匹配时。相反,有一些区域,主要是在边缘,图像算法似乎使用了某种插值。
是否有一个选项可以停止插值并保留确切的数据(例如 7 总是在 PNG 中获取 rgb(7,7,7)?
如果您有一个 2D numpy 数组,那么您将保存为灰度 PNG,因此您永远不会获得 rgb 图像(只有一个通道)。我不确定你所说的单值是什么意思,也许是单精度浮点数?尽管 PIL 支持单精度浮点数,但 PNG 不支持。保存为 PNG,您可以使用每通道 8 位(默认)或每通道 16 位。这意味着您的数组将被缩放到最大 2^8/2^16(8/16 位),并转换为整数。正是在这种转换中,结果可能会略有不同。
scipy.misc.image
似乎没有保存为 16 位的选项,所以它总是会写一个 8 位的 PNG 。但是你可以scipy.misc.toimage
用来创建一个 16 位的图像,只是一定要通过mode='I'
. 还要确保指定数组最小值和最大值以避免缩放。以下是如何使用它来保存 16 位 png:
import numpy as np
import scipy.misc
a = np.random.uniform(0, 2**16 - 1, (500, 500)).astype('int32')
img = scipy.misc.toimage(a, high=np.max(a), low=np.min(a), mode='I')
img.save('my16bit.png')
# check that you got the same values
b = scipy.misc.imread('my16bit.png')
b.dtype
# dtype('int32')
np.array_equal(a, b)
# True
请注意,在此示例中,我使用int32
了数据类型。但是,数据仍必须适合uint16
. 如果您输入负值或大于 2^16 的值,这些值将在保存到 PNG 时被剪裁。相反,即使sp.misc.imread
读取为int32
,数据也永远不会超过uint16
。
总之:如果您想将完全相同的 numpy 数组写入 PNG,您需要确保它是uint8/uint16
类型,并且您将正确的传递high/low/mode
给scipy.misc.toimage
.