如何将灰度图像转换为像素值列表?

问题描述:

我想创建一个需要灰度,24 * 24像素图像文件(我还没有决定类型,所以建议欢迎)的python程序,并将其转换为从0(白色)像素值列表,到255(黑色)。如何将灰度图像转换为像素值列表?

我打算使用这个数组创建一个类似MNIST的图片的字节文件,它可以被Tensor-Flow手写识别算法识别。

我发现Pillow library是这一任务是最有用的,通过迭代的每个像素,并将其值从PIL进口图片

img = Image.open('eggs.png').convert('1') 
rawData = img.load() 
data = [] 
for y in range(24): 
    for x in range(24): 
     data.append(rawData[x,y]) 

附加到阵列 然而,这个解决方案有两个问题(1 )像素值不是以整数存储,而是像素对象,不能进一步数学操作,因此无用。 (2)即使枕头文档陈述:

访问个别像素是相当缓慢。如果您要遍历图像中的所有像素,使用Pillow API的其他部分可能会更快。

+0

当我在我的机器上运行你的代码时,'data'是一个常规整数列表。 – Kevin

+1

该文档可能指的是[getdata](https://pillow.readthedocs.io/en/3.4.x/reference/Image.html#PIL.Image.Image。getdata),我预计它比每像素访问更快。 – Kevin

+0

我不知道任何Python库对于单个像素访问都不慢。 – Douglas

您可以将图像数据转换成Python列表(或列表中的链表)是这样的:

from PIL import Image 

img = Image.open('eggs.png').convert('L') # convert image to 8-bit grayscale 
WIDTH, HEIGHT = img.size 

data = list(img.getdata()) # convert image data to a list of integers 
# convert that to 2D list (list of lists of integers) 
data = [data[offset:offset+WIDTH] for offset in range(0, WIDTH*HEIGHT, WIDTH)] 

# At this point the image's pixels are all in memory and can be accessed 
# individually using data[row][col]. 

# For example: 
for row in data: 
    print(' '.join('{:3}'.format(value) for value in row)) 

# Here's another more compact representation. 
chars = '@%#*+=-:. ' # Change as desired. 
scale = (len(chars)-1)/255. 
print() 
for row in data: 
    print(' '.join(chars[int(value*scale)] for value in row)) 

下面是我用于测试一个小型的24x24 RGB eggs.png图像的放大版本:

enlarged version of eggs.png

下面是从访问的第一个例子中的输出:

screenshot output from test image

在这里从第二个例子的输出:

@ @ % * @ @ @ @ % - . * @ @ @ @ @ @ @ @ @ @ @ @ 
@ @ . . + @ # .  = @ @ @ @ @ @ @ @ @ @ @ @ 
@ *    . . * @ @ @ @ @ @ @ @ @ @ @ @ 
@ #  . . . .  + % % @ @ @ @ # = @ @ @ @ 
@ %  . : - - - :  % @ % :  # @ @ @ 
@ #  . = = - - - = - . . = =   % @ @ @ 
@ =  - = : - - : - = . .  . : . % @ @ @ 
%  . = - - - - : - = . . - = = = - @ @ @ 
= . - = - : : = + - : . - = - : - = : * % 
- . . - = + = - . . - = : - - - = .  - 
= . : : . - - .  : = - - - - - = . . % 
% : : .  . : - - . : = - - - : = :  # @ 
@ # : . . = = - - = . = + - - = - . . @ @ 
@ @ #  . - = : - : = - . - = = : . .  # @ 
@ @ %  : = - - - : = -  : - . . . - @ 
@ @ *  : = : - - - = . . - . .  . + @ 
@ #  . = - : - = :  : : . - % @ @ @ 
*  . . . : = = - : . . - .  - @ @ @ @ @ 
* . .  . : . . . - = . = @ @ @ @ @ @ 
@ :  - -  . . . .  # @ @ @ @ @ @ @ @ 
@ @ = # @ @ *  . .  . - @ @ @ @ @ @ @ @ @ 
@ @ @ @ @ @ @ . . . # @ @ @ @ @ @ @ @ @ @ @ 
@ @ @ @ @ @ @ -  . % @ @ @ @ @ @ @ @ @ @ @ @ 
@ @ @ @ @ @ @ # . : % @ @ @ @ @ @ @ @ @ @ @ @ @ 

访问像素数据现在应该比使用对象img.load()返回(和值将在0..255范围内的整数更快)。

您可以通过访问r,g或b值来访问每个像素的灰度值,这对于灰度图像来说都是相同的。

I.e.

img = Image.open('eggs.png').convert('1') 
rawData = img.load() 
data = [] 
for y in range(24): 
    for x in range(24): 
     data.append(rawData[x,y][0]) 

这并不能解决访问速度问题。

我对scikit-image比枕头更熟悉。在我看来,如果你在列出灰度值之后,可以使用scikit-image,它将图像存储为numpy数组,并使用img_as_ubyte将图像表示为一个uint数组,其中包含0到255之间的值。

Images are NumPy Arrays为查看代码的外观提供了一个很好的起点。