【问题标题】:Retain unchanged data when saving Numpy array to image with Scipy imsave使用 Scipy imsave 将 Numpy 数组保存到图像时保留未更改的数据
【发布时间】:2012-12-03 18:48:33
【问题描述】:

使用 Scipy toimageimsave 保存二维 Numpy 数组(单个值)时,像素值与 Numpy 数组中的像素值不完全匹配。相反,有些区域,主要是在边缘,图像算法似乎使用了某种插值。

是否有一个选项可以停止插值并保留准确的数据(例如,7 总是在 PNG 中获取 rgb(7,7,7)?

【问题讨论】:

    标签: python image numpy scipy python-imaging-library


    【解决方案1】:

    如果您有一个 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@.

    【讨论】:

    • 是否有一些关于如何使用 PIL 进行图像转换和保存关于数据类型、精度和文件格式的适当文档/教程?
    • @Juh_,有一些关于 PIL 图像转换的教程(只是谷歌),但我对数据类型和精度知之甚少。大多数图像都是 24 位的(每个通道 8 位,所以 uint8),因此精度和数据类型的问题并不经常出现。
    • 谷歌搜索时,我发现的只是基本教程,或“16bits tiff”等具体问题。就我而言,我有(科学)图像数据,我喜欢以可查看的格式(即图像文件)保存,尽可能压缩,但不会损失精度。我很想有一个表格,列出每种情况下的最佳保存方法。
    • 听起来你想要无损压缩,它排除了除 png 之外的大多数格式。您是否考虑过使用fits?它是一种非常常见的科学图像数据格式(大多数望远镜都编写 FITS 文件)。您可以使用pyfits 在 Python 中与它交互。它支持压缩(我认为是 gzip 和 rice),但我用的不多。
    猜你喜欢
    • 2017-08-02
    • 1970-01-01
    • 2020-01-15
    • 2010-10-28
    • 2023-03-15
    • 1970-01-01
    • 2020-02-17
    • 2021-02-20
    相关资源
    最近更新 更多