如何在PIL和numpy之间转换模式为“1”的图像?

Cli*_*pit 6 python numpy python-imaging-library

我是 Python 图像处理的新手,遇到了一个奇怪的问题。

例如,我有一个 2*2 的黑白位图图像,其像素如下:

黑,白

白色 黑色

使用 PIL 并将其转换为 numpy:

>>> import Image
>>> import numpy
>>> im = Image.open('test.bmp')
>>> im
<BmpImagePlugin.BmpImageFile image mode=1 size=2x2 at 0x95A54EC>
>>> numpy.asarray(im)
array([[ True,  True],
       [False, False]], dtype=bool)
>>>
Run Code Online (Sandbox Code Playgroud)

让我感到困惑的是数组中像素的顺序。为什么不[[True, False], [False, True]]呢?谢谢。


更新:位图在这里:http : //njuer.us/clippit/test.bmp

jte*_*ace 6

使用该1模式从 numpy 转换为/从 numpy 似乎存在一些错误。

如果您将其转换为L第一个,则可以正常工作:

>>> im
<BmpImagePlugin.BmpImageFile image mode=1 size=2x2 at 0x17F17E8>
>>> im2 = im.convert('L')
>>> numpy.asarray(im2)
array([[  0, 255],
       [255,   0]], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)

此外,如果您尝试将boolnumpy 数组转换为 PIL,则会得到奇怪的结果:

>>> testarr = numpy.array([[True,False],[True,False]], dtype=numpy.bool)
>>> testpil = Image.fromarray(testarr, mode='1')
>>> numpy.asarray(testpil)
array([[False, False],
       [False, False]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

但是,完全相同的事情可以uint8正常工作:

>>> testarr = numpy.array([[255,0],[0,255]], dtype=numpy.uint8)
>>> Image.fromarray(testarr)
<Image.Image image mode=L size=2x2 at 0x1B51320>
>>> numpy.asarray(Image.fromarray(testarr))
array([[255,   0],
       [  0, 255]], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)

因此,如果您需要将其保存为该格式,我建议将其L用作中间数据类型,然后1在保存之前转换为。像这样的东西:

>>> im
<BmpImagePlugin.BmpImageFile image mode=1 size=2x2 at 0x17F17E8>
>>> im2 = im.convert('L')
>>> arr = numpy.asarray(im2)
>>> arr
array([[  0, 255],
       [255,   0]], dtype=uint8)
>>> arr = arr == 255
>>> arr
array([[False,  True],
       [ True, False]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

然后转换回来:

>>> backarr = numpy.zeros(arr.shape, dtype=numpy.uint8)
>>> backarr[arr] = 255
>>> backarr
array([[  0, 255],
       [255,   0]], dtype=uint8)
>>> Image.fromarray(backarr).convert('1')
<Image.Image image mode=1 size=2x2 at 0x1B41CB0>
Run Code Online (Sandbox Code Playgroud)