简体   繁体   中英

How to convert a grayscale image into a list of pixel values?

I am trying to create a python program which takes a grayscale, 24*24 pixel image file (I haven't decided on the type, so suggestions are welcome) and converts it to a list of pixel values from 0 (white) to 255 (black).

I plan on using this array for creating a MNIST -like bytefile of the picture, that can be recognized by Tensor-Flow handwriting recognition algorithms.

I have found the Pillow library to be the most useful in this task, by iterating over each pixel and appending its value to an array

from PIL import Image

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])

Yet this solution has two problems:

  1. The pixel values are not stored as integers, but pixel objects which cannot be further mathematically manipulated and are therefore useless.
  2. Even the Pillow docs state that:

    Accessing individual pixels is fairly slow. If you are looping over all of the pixels in an image, there is likely a faster way using other parts of the Pillow API.

You can convert the image data into a Python list (or list-of-lists) like this:

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))

Here's an enlarged version of a small 24x24 RGB eggs.png image I used for testing:

放大版eggs.png

Here's the output from the first example of access:

测试图像的屏幕截图输出

And here the output from the second example:

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

Access to the pixel data should now be faster than using the object img.load() returns (and the values will be integers in the range of 0..255).

You can access the greyscale value of each individual pixel by accessing the r, g, or b value, which will all be the same for a greyscale image.

Ie

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])

This doesn't solve the problem of access speed.

I'm more familiar with scikit-image than Pillow. It seems to me that if all you are after is listing the greyscale values, you could use scikit-image, which stores images as numpy arrays, and use img_as_ubyte to represent the image as a uint array, containing values between 0 and 255.

Images are NumPy Arrays provides a good starting point to see what the code looks like.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM