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
Save numpy array as image with high precision (16 bits) with scikit-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.io
package 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 freeimage
library 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))
会将其恢复为原始形状。