代码之家  ›  专栏  ›  技术社区  ›  uhoh Jacob

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

  •  0
  • uhoh Jacob  · 技术社区  · 7 年前

    我想 明白为什么 ,当我转换PIL图像时 imageRGB 到浮点数组 arrayRGB_f 使用matplotlib的 imshow() 如果没有cmap,它看起来要么是黑色的,要么是奇怪的,不可读的,尽管PIL's imageRGB.show() 看起来不错,每个单独的r,g,b通道都显示有 cmap='gray' 看起来也不错。

    我有办法,但我不明白为什么会这样。

    matplotlib.__version__ 回报 '2.0.2' 我在用MacOS和一个水蟒装置。

    看这个 answer 有关将ttf呈现转换为1bit的详细信息。

    仅供参考,打印报表的输出为:

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

    fontname   = 'default' 
    

    图像rgb.show()

    enter image description here

    plt.imshow()

    enter image description here

    fontname   = 'Arial Unicode.ttf' 
    

    图像rgb.show()

    enter image description here

    节目表()

    enter image description here

    font   = ImageFont.truetype(fontname, 20)
    

    图像rgb.show()

    enter image description here

    节目表()

    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 回复  |  直到 7 年前
        1
  •  0
  •   uhoh Jacob    7 年前

    我找不到理想的复制品,所以我会贴出答案。

    作为@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()
    

    有关更长时间的讨论,请参见 this this .