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

tsa*_*lis 11 python numpy image-processing scipy scikit-image

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

这是我尝试过的主要内容:

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
Run Code Online (Sandbox Code Playgroud)

生产:

array([[    0, 21845],
       [43690, 65535]], dtype=uint16)
Run Code Online (Sandbox Code Playgroud)

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

# try with pil:
io.use_plugin('pil')
io.imsave('test_16bit.png', im)
im2 = io.imread('test_16bit.png')
im2
Run Code Online (Sandbox Code Playgroud)

生产:

array([[  0,  85],
       [170, 255]], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)

所以在某处(无论是写入还是读取)我都失去了精确度.然后我尝试使用matplotlib插件:

# try with matplotlib:
io.use_plugin('matplotlib')
io.imsave('test_16bit.png', im)
im3 = io.imread('test_16bit.png')
im3
Run Code Online (Sandbox Code Playgroud)

给我一个32位浮点数:

array([[ 0.        ,  0.33333334],
       [ 0.66666669,  1.        ]], dtype=float32)
Run Code Online (Sandbox Code Playgroud)

但我怀疑这是32位,因为我保存了16位uint到文件.如果有人能指出我出错的地方会很棒.我希望这也扩展到3D阵列(即每个颜色通道节省16位,每个图像48位).

更新:

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

abu*_*dis 11

你想用这个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')
Run Code Online (Sandbox Code Playgroud)

结果:

[[    0 21845]
 [43690 65535]]
Run Code Online (Sandbox Code Playgroud)

对于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')
Run Code Online (Sandbox Code Playgroud)

请注意,读取的图像是翻转的,所以类似的东西np.fliplr(np.flipud(im2))会使它变成原始形状.

  • 很好,谢谢阿布迪斯。对于其他有此问题的用户:我在OSX上;我用homebrew(`brew install freeimage`)安装了freeimage,然后上面的(io.use_plugin('freeimage')`)工作正常。 (2认同)