我运行以下代码:
colored = np.empty((299, 299, 3), dtype=float) # dtype=`uint16` doesn't work too!
colored[:, :, 0] = image
colored[:, :, 1] = image
colored[:, :, 2] = image
如果我绘制image
(uint16
的二维数组),我可以看到正确的图片。但如果我绘制colored
数组,那么我会得到以下垃圾图片:
我使用以下代码进行绘图:
import matplotlib.pyplot as plt
plt.imshow(colored, cmap='gray')
plt.show()
当我绘制image
时,它有效。当我绘制colored
时,它没有。这里发生了什么,我该如何解决?
答案 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
故事的寓意是,如果您将3D浮点数组传递给plt.imshow
,则值必须介于0和1(或NaN)之间,否则您可能会得到(图形)mojibake。