【发布时间】:2012-12-03 18:48:33
【问题描述】:
使用 Scipy toimage 或 imsave 保存二维 Numpy 数组(单个值)时,像素值与 Numpy 数组中的像素值不完全匹配。相反,有些区域,主要是在边缘,图像算法似乎使用了某种插值。
是否有一个选项可以停止插值并保留准确的数据(例如,7 总是在 PNG 中获取 rgb(7,7,7)?
【问题讨论】:
标签: python image numpy scipy python-imaging-library
使用 Scipy toimage 或 imsave 保存二维 Numpy 数组(单个值)时,像素值与 Numpy 数组中的像素值不完全匹配。相反,有些区域,主要是在边缘,图像算法似乎使用了某种插值。
是否有一个选项可以停止插值并保留准确的数据(例如,7 总是在 PNG 中获取 rgb(7,7,7)?
【问题讨论】:
标签: python image numpy scipy python-imaging-library
如果您有一个 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 传递给 @ 987654334@.
【讨论】:
uint8),因此精度和数据类型的问题并不经常出现。