今天在使用 imshow() 的过程中踩了个坑,问题解决了,这里记录一下。
通常我们读取一张图片,返回的是一个多维数组,彩色图RGB( α \alpha α)通道,灰度图单通道。每个通道是个二维数组,其中每个像素的数值大小为0 ~1,或者0 ~255,0为黑色,1为白色。
问题就出在这,今天,无论我给 imshow() 传入的是全为0的数组array1,亦或者是全为1的数组array2,最终显示的图像全为黑色?但是手动输入0、1 混合数组array3,却能显示黑白两色。代码和结果如下所示。
fig, ax = plt.subplots(1, 3)
array1 = np.zeros((2, 2))
array2 = np.ones((2, 2))
array3 = [[0,0], [1,1]]
im1 = ax[0].imshow(array1, cmap="gray")
im2 = ax[1].imshow(array2, cmap="gray")
im3 = ax[2].imshow(array3, cmap="gray")
ax[0].set_title("array1")
ax[1].set_title("array2")
ax[2].set_title("array3")
plt.subplots_adjust(wspace=1)
百思不得其解,去搜了下doc,豁然开朗。有个小细节之前一直没注意到。
如上图红线所述,对于传入的二维数组,imshow函数内部会先对其数据做归一化(0~1),接着再根据cmap的参数,映射到所选的颜色区间。因此,无论对于array1, 还是array2,由于数据之间没有分布,全为1或全为0,在第一步归一化所得的结果都为零,所以很自然地映射出来的颜色均为黑色。但如果传入的数据有分布,如array3,则“泾渭分明”。
此外,对于传入多通道数组则无此困扰,效果如下:
fig, ax = plt.subplots(1, 3)
array1 = np.zeros((2,2,3))
array2 = np.ones((2,2,3))
array3 = np.random.random((2,2,3))
ax[0].imshow(array1)
ax[1].imshow(array2)
ax[2].imshow(array3)
ax[0].set_title("zeros")
ax[1].set_title("ones")
ax[2].set_title("random")
plt.subplots_adjust(wspace=1)