Python 使用 scikit-image 将 numpy 数组保存为高精度(16 位)图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24240039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:17:40  来源:igfitidea点击:

Save numpy array as image with high precision (16 bits) with scikit-image

pythonimage-processingnumpyscipyscikit-image

提问by tsawallis

I am working with 2D floating-point numpy arrays that I would like to save to greyscale .png files with high precision (e.g. 16 bits). I would like to do this using the scikit-image skimage.iopackage if possible.

我正在使用 2D 浮点 numpy 数组,我想以高精度(例如 16 位)保存到灰度 .png 文件。skimage.io如果可能的话,我想使用 scikit-image包来做到这一点。

Here's the main thing I've tried:

这是我尝试过的主要事情:

import numpy as np
from skimage import io, exposure, img_as_uint, img_as_float

im = np.array([[1., 2.], [3., 4.]], dtype='float64')
im = exposure.rescale_intensity(im, out_range='float')
im = img_as_uint(im)
im

produces:

产生:

array([[    0, 21845],
       [43690, 65535]], dtype=uint16)

First I tried saving this as an image then reloading using the Python Imaging Library:

首先,我尝试将其保存为图像,然后使用 Python 图像库重新加载:

# try with pil:
io.use_plugin('pil')
io.imsave('test_16bit.png', im)
im2 = io.imread('test_16bit.png')
im2

produces:

产生:

array([[  0,  85],
       [170, 255]], dtype=uint8)

So somewhere (in either the write or read) I have lost precision. I then tried with the matplotlib plugin:

所以在某个地方(无论是写还是读)我都失去了精度。然后我尝试使用 matplotlib 插件:

# try with matplotlib:
io.use_plugin('matplotlib')
io.imsave('test_16bit.png', im)
im3 = io.imread('test_16bit.png')
im3

gives me a 32-bit float:

给我一个 32 位浮点数:

array([[ 0.        ,  0.33333334],
       [ 0.66666669,  1.        ]], dtype=float32)

but I doubt this is really 32-bits given that I saved a 16-bit uint to the file. It would be great if someone could point me to where I'm going wrong. I would like this to extend to 3D arrays too (i.e. saving 16 bits per colour channel, for 48 bits per image).

但我怀疑这真的是 32 位,因为我将 16 位 uint 保存到文件中。如果有人能指出我出错的地方,那就太好了。我也希望将其扩展到 3D 数组(即每个颜色通道节省 16 位,每个图像节省 48 位)。

UPDATE:

更新:

The problem is with imsave. The images are 8 bits per channel. How can one use io.imsave to output a high bit-depth image?

问题在于 imsave。图像为每通道 8 位。如何使用 io.imsave 输出高位深图像?

采纳答案by abudis

You wanna use the freeimagelibrary to do so:

你想使用freeimage图书馆这样做:

import numpy as np
from skimage import io, exposure, img_as_uint, img_as_float

io.use_plugin('freeimage')

im = np.array([[1., 2.], [3., 4.]], dtype='float64')
im = exposure.rescale_intensity(im, out_range='float')
im = img_as_uint(im)

io.imsave('test_16bit.png', im)
im2 = io.imread('test_16bit.png')

Result:

结果:

[[    0 21845]
 [43690 65535]]

As for 3D arrays, you need to construct the array properly and then it'll work:

至于 3D 数组,您需要正确构造数组,然后它才能工作:

# im = np.array([[1, 2.], [3., 4.]], dtype='float64')
im = np.linspace(0, 1., 300).reshape(10, 10, 3)
im = exposure.rescale_intensity(im, out_range='float')
im = img_as_uint(im)

io.imsave('test_16bit.png', im)
im2 = io.imread('test_16bit.png')

Note that the read image is flipped, so something like np.fliplr(np.flipud(im2))will bring it to original shape.

请注意,读取的图像已翻转,因此类似的操作np.fliplr(np.flipud(im2))会将其恢复为原始形状。