【问题标题】:How can i transform my binary numpy list of arrays to an image?如何将我的二进制 numpy 数组列表转换为图像?
【发布时间】:2018-06-19 14:26:46
【问题描述】:
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 1 1 1 0 0 0 0 0 1 1 0 0 3 3 0 0 0 4 4 0 0 0 5 5 5 5 0 0 2 2 2 2 2 0 2 2 2 2 2 0 0 0 6 6 6 6 6 6 0 6 6 6 6]
 [0 1 1 0 0 0 0 0 0 0 0 0 0 3 3 0 0 0 4 4 0 0 5 5 5 5 5 5 0 2 2 2 2 2 2 2 2 2 2 2 2 0 0 6 6 6 6 6 6 6 6 6 6 6]
 [1 1 1 0 0 0 0 0 0 0 0 0 0 3 3 0 0 0 4 4 0 5 5 5 0 0 5 5 5 0 2 2 0 0 2 2 0 0 0 2 2 0 0 6 6 0 0 6 6 6 0 0 6 6]
 [1 1 1 0 0 0 0 0 0 0 0 0 0 3 3 0 0 0 4 4 0 5 5 5 5 0 0 0 0 0 2 2 0 2 2 2 0 0 0 2 2 2 0 6 6 0 0 0 6 6 0 0 6 6]
 [1 1 1 0 0 0 0 0 0 0 0 0 0 3 3 0 0 0 4 4 0 0 5 5 5 5 5 5 0 0 2 2 0 2 2 2 0 0 0 2 2 2 0 6 6 0 0 0 6 6 0 0 6 6]
 [0 1 1 0 0 0 0 0 0 7 0 0 0 3 3 0 0 0 4 4 0 0 0 0 5 5 5 5 5 0 2 2 0 2 2 2 0 0 0 2 2 2 0 6 6 0 0 0 6 6 0 0 6 6]]

作为第一步,我希望不同于 0 的像素为白色,而 0 像素为黑色。我做了什么将无 0 值全部转换为 1:

binary_transform = np.array(labels).astype(bool).astype(int)

它起作用了,然后我想将 1 和 0 的数组列表转换为图像,我尝试了什么:

from PIL import Image

img = Image.fromarray(binary_transform, '1')
img.save('image.png')

Image.fromarray 的文档可以在这里找到https://pillow.readthedocs.io/en/3.1.x/reference/Image.html

它没有工作,然后我尝试了以下方法:

import png

png.from_array(binary_transform, 'L').save('image.png')

参考文档'L' 是灰度,而我想要二进制但我没有看到二进制选项,文档https://pythonhosted.org/pypng/png.html

我收到了这个错误ValueError: bitdepth (64) must be a positive integer <= 16

【问题讨论】:

    标签: python arrays image numpy image-processing


    【解决方案1】:

    虽然你没有明确地这么说,但你说“作为第一步......”的事实让我觉得你正朝着灰度调色板图像前进:

    import numpy as np
    from PIL import Image
    labels=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
     [0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
     [0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
     [0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
     [0,1,1,1,0,0,0,0,0,1,1,0,0,3,3,0,0,0,4,4,0,0,0,5,5,5,5,0,0,2,2,2,2,2,0,2,2,2,2,2,0,0,0,6,6,6,6,6,6,0,6,6,6,6],
     [0,1,1,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,4,4,0,0,5,5,5,5,5,5,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,6,6,6,6,6,6,6,6,6,6,6],
     [1,1,1,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,4,4,0,5,5,5,0,0,5,5,5,0,2,2,0,0,2,2,0,0,0,2,2,0,0,6,6,0,0,6,6,6,0,0,6,6],
     [1,1,1,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,4,4,0,5,5,5,5,0,0,0,0,0,2,2,0,2,2,2,0,0,0,2,2,2,0,6,6,0,0,0,6,6,0,0,6,6],
     [1,1,1,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,4,4,0,0,5,5,5,5,5,5,0,0,2,2,0,2,2,2,0,0,0,2,2,2,0,6,6,0,0,0,6,6,0,0,6,6],
     [0,1,1,0,0,0,0,0,0,7,0,0,0,3,3,0,0,0,4,4,0,0,0,0,5,5,5,5,5,0,2,2,0,2,2,2,0,0,0,2,2,2,0,6,6,0,0,0,6,6,0,0,6,6]]
    binary_transform = np.array(labels).astype(np.uint8)
    img = Image.fromarray(binary_transform, 'P')
    img.save('image.png')
    

    请注意,出于显示目的,我已经调整了图像的大小并进行了对比度拉伸。

    如果您真的只想要一个真正的二进制黑白图像,请使用:

    binary_transform = np.array(labels).astype(np.uint8)
    binary_transform[binary_transform>0] = 255
    img = Image.fromarray(binary_transform, 'L')
    img.save('image.png')
    

    【讨论】:

    • 其实不是灰度图,是连通分量函数的输出应用于灰度图(cv2.connectedComponents)
    • 我猜是 Connected Components 标签 :-)
    【解决方案2】:

    如果我理解正确,您希望图像显示为二进制,即只有黑色和白色,没有灰色。如果是这样的话,OpenCV 就是你的朋友:

    import cv2
    import numpy as np
    
    binary_transform = np.array(labels).astype(np.uint8)
    
    _,thresh_img = cv2.threshold(binary_transform, 0, 255, cv2.THRESH_BINARY)
    
    cv2.imwrite('image.png', thresh_img)
    

    当然 PIL 也可以,您只需要调整非零值即可。

    binary_transform = np.array(labels).astype(np.uint8)
    binary_transform[binary_transform > 0] = 255
    
    img = Image.fromarray(binary_transform, 'L')
    img.save('image.png')
    

    【讨论】:

    • 很酷,并且 +1 以两种不同的方式进行!
    【解决方案3】:

    其他答案(都很好!)使用 OpenCV 或 PIL。以下是使用 numpngw 创建图像的方法,这是我编写的一个小型库,用于从 numpy 数组创建 PNG 文件。

    首先,这是我的示例数据:

    In [173]: x
    Out[173]: 
    [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 1, 1, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 1, 1, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 1, 1, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 1, 1, 1, 1, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
     [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
    

    使用numpngw.write_png()创建图像:

    In [174]: import numpy as np
    
    In [175]: import numpngw
    
    In [176]: numpngw.write_png("foo.png", (np.array(x) > 0).astype(np.uint8), bitdepth=1)
    

    这是图片:

    【讨论】:

      猜你喜欢
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      • 2018-11-22
      • 2011-12-04
      • 2012-09-22
      • 1970-01-01
      相关资源
      最近更新 更多