为什么在Matplotlib中无法正确显示由PIL draw.text()图像制成的数组?

时间:2018-08-08 20:26:55

标签: python-2.7 matplotlib python-imaging-library

我想理解为什么,当我将PIL图像imageRGB转换为浮点数组arrayRGB_f并使用不带cmap的matplotlib的imshow()时即使PIL的imageRGB.show()看起来还不错,并且看起来cmap='gray'的每个单独的r,g,b通道也看起来还不错,但它们看起来还是黑色的,还是奇怪且难以辨认的。

我有解决方法,但是我不明白为什么会发生这种情况。

matplotlib.__version__返回'2.0.2',并且我正在使用MacOS和Anaconda安装。

有关将ttf渲染转换为1位的更多信息,请参见answer

打印语句的输出为:

float64 (41, 101, 3)
int64 (41, 101, 3)
int64 (41, 101)
int64 (41, 101)

fontname   = 'default' 

imageRGB.show()

enter image description here

plt.imshow()

enter image description here

fontname   = 'Arial Unicode.ttf' 

imageRGB.show()

enter image description here

plt.imshow()

enter image description here

font   = ImageFont.truetype(fontname, 20)

imageRGB.show()

enter image description here

plt.imshow()

enter image description here

from PIL import Image, ImageDraw, ImageFont
import numpy as np
import matplotlib.pyplot as plt

# fontname   = 'Arial Unicode.ttf' 
fontname   = 'default' 

if fontname == 'default':
    font   = ImageFont.load_default()
else:
    font   = ImageFont.truetype(fontname, 12)

string     = "Hello " + fontname[:6]
ww, hh     = 101, 41
threshold  = 80   # https://stackoverflow.com/a/47546095/3904031

imageRGB   = Image.new('RGB', (ww, hh))
draw       = ImageDraw.Draw(imageRGB)
image8bit  = draw.text((10, 12), string, font=font,
                       fill=(255, 255, 255, 255))  # R, G, B alpha

image8bit  = imageRGB.convert("L")
image1bit  = image8bit.point(lambda x: 0 if x < threshold else 1, mode='1')  # https://stackoverflow.com/a/47546095/3904031

arrayRGB   = np.array(list(imageRGB.getdata())).reshape(hh, ww, 3)
arrayRGB_f = arrayRGB.astype(float)

array8bit  = np.array(list(image8bit.getdata())).reshape(hh, ww)
array1bit  = np.array(list(image1bit.getdata())).reshape(hh, ww)

for a in (arrayRGB_f, arrayRGB, array8bit, array1bit):
    print a.dtype, a.shape

imageRGB.show()

if True:
    plt.figure()

    a = arrayRGB_f
    plt.subplot(2, 2, 1)
    plt.imshow(a)  # , interpolation='nearest',  cmap='gray',

    for i in range(3):
        plt.subplot(2, 2, 2+i)
        plt.imshow(a[:, :, i], cmap='gray') 

    plt.suptitle('arrayRGB_f, fontname = ' + fontname)
    plt.show()

1 个答案:

答案 0 :(得分:0)

我找不到理想的副本,所以我将发布答案。

作为@ImportanceOfBeingErnest mentions,当给.imshow()n x m x 3数组n x m x 4时,期望归一化数组在0.0到1.0之间。

做到这一点的最佳方法是:

arrayRGB_f = arrayRGB.astype(float)/255.

尽管这似乎也可行:

arrayRGB_f = arrayRGB.astype(float)
arrayRGB_f = arrayRGB_f / arrayRGB_f.max()

有关更多讨论,请参见thisthis