读取图像的字节

时间:2018-03-16 23:05:25

标签: python python-3.x image byte pillow

我从文件中读取了784个字节(28x28图像):

with open(self.filePath, 'rb') as f:
    aLetter = f.read(784)
    print ('A Letter',aLetter)
    image = Image.frombytes('1',[79,78],aLetter)

当我打印并扔掉那封'在文本区中,我计算764个字节,而不是784个字节。但是当我在frombytes中将字母传递给枕头时,我可以将其传递给大小为[79,78]个字节的数组。

是什么给出的?我有多少字节?如何让我的784字节数组创建一个28x28字母图像? Pillow如何看到比那里更多的字节?

对于那些感兴趣的人,数据来自这里: http://cis.jhu.edu/~sachin/digit/digit.html

哪个解释:

  

每个训练示例的大小为28x28像素。像素存储为无符号字符(1个字节),取0到255之间的值

1 个答案:

答案 0 :(得分:0)

你没有764个字节,因为如果你那么短,就会抛出异常:

>>> Image.frombytes('1', [79, 78], bytes(764))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.7/lib/python3.7/site-packages/PIL/Image.py", line 2331, in frombytes
    im.frombytes(data, decoder_name, args)
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.7/lib/python3.7/site-packages/PIL/Image.py", line 786, in frombytes
    raise ValueError("not enough image data")
ValueError: not enough image data

虽然您可以使用784字节制作过大的图像:

>>> Image.frombytes('1', [79, 78], bytes(784))
<PIL.Image.Image image mode=1 size=79x78 at 0x104D2ACF8>

PIL为79 x 78图像接受的最小字节数为780字节。因为您正在创建'1'模式图像,所以每个字节都会有8个像素,因此您只需要math.ceil(79 / 8)或每行10个字节。

要查看bytes对象的长度,请打印len()函数结果:

>>> with open('data0', 'rb') as f:
...     letter_data = f.read(28 * 28)
...     print(len(letter_data))
...
784

但是您使用的是错误的数据模式。 '1'开启或关闭图片格式,只有0或1有意义。图像训练数据使用每个像素的完整字节或256个可能的值,因此您希望使用'L'模式加载它:

letter_image = Image.frombytes('L', (28, 28), letter_data)

使用'L'时,会使用每个字节的256个可能值,并且必须传入28 * 28个字节,如果实际上只有764个字节,则会出错:

>>> image = Image.frombytes('L', (28, 28), letter_data[:764])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.7/lib/python3.7/site-packages/PIL/Image.py", line 2331, in frombytes
    im.frombytes(data, decoder_name, args)
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.7/lib/python3.7/site-packages/PIL/Image.py", line 786, in frombytes
    raise ValueError("not enough image data")
ValueError: not enough image data

使用letter_image.save('/tmp/0.png')data0中的第一张图片将导出为PNG图片,如下所示:

First training image from data0, a white circle on black