为什么我不能在Python中将uint16数组分配给数组向量?

时间:2017-10-07 20:47:56

标签: python arrays numpy floating-point type-conversion

我运行以下代码:

    colored = np.empty((299, 299, 3), dtype=float) # dtype=`uint16` doesn't work too!
    colored[:, :, 0] = image
    colored[:, :, 1] = image
    colored[:, :, 2] = image

如果我绘制imageuint16的二维数组),我可以看到正确的图片。但如果我绘制colored数组,那么我会得到以下垃圾图片:

enter image description here

我使用以下代码进行绘图:

    import matplotlib.pyplot as plt
    plt.imshow(colored, cmap='gray')
    plt.show()

当我绘制image时,它有效。当我绘制colored时,它没有。这里发生了什么,我该如何解决?

1 个答案:

答案 0 :(得分:2)

当传递给imshow的数组是3维且具有浮点dtype时, plt.show()来电this piece of code

if x.ndim == 3:
    ...    
    if xx.dtype.kind == 'f':
        if bytes:
            xx = (xx * 255).astype(np.uint8)
    return xx

因此colored中的值乘以255,然后astype d乘以np.uint8。 这种情况发生在之前将值标准化为区间[0, 1]。您可以通过在matplotlib/cm.py文件中添加print语句来验证这一点:

if x.ndim == 3:
    ...    
    if xx.dtype.kind == 'f':
        if bytes:
            print(xx.max())
            xx = (xx * 255).astype(np.uint8)
    return xx

并运行此脚本:

import numpy as np
import matplotlib.pyplot as plt

maxval = np.iinfo('uint16').max
uint16_image = np.linspace(0, maxval, (16**2)).astype('uint16')
uint16_image = uint16_image.reshape(16, 16)

colored = np.empty(uint16_image.shape + (3,), dtype=float)
colored[:, :, 0] = uint16_image
colored[:, :, 1] = uint16_image
colored[:, :, 2] = uint16_image

fig, ax = plt.subplots(nrows=2)
ax[0].imshow(uint16_image)
ax[1].imshow(colored)
plt.show()

打印

65535.0
65535.0

并显示 enter image description here

故事的寓意是,如果您将3D浮点数组传递给plt.imshow,则值必须介于0和1(或NaN)之间,否则您可能会得到(图形)mojibake。