Cómo convertir una imagen en escala de grises en una lista de valores de píxeles?

Estoy tratando de crear un programa en python que se lleva a una escala de grises, de 24*24 píxeles de la imagen de archivo (aún no he decidido sobre el tipo, así que se admiten sugerencias) y la convierte en una lista de valores de los píxeles de 0 (negro) a 255 (blanco).

I plan sobre el uso de esta matriz para la creación de un MNIST-como bytefile de la imagen, que puede ser reconocido por el Tensor de Flujo de reconocimiento de escritura a mano de los algoritmos.

He encontrado la Almohada de la biblioteca ser el más útil en esta tarea, por iterar sobre cada píxel y anexar su valor a una matriz
de PIL importar Imagen

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

Sin embargo, esta solución tiene dos problemas: (1) los valores de Los píxeles no se almacenan como números enteros, pero de píxeles de los objetos que no pueden ser matemáticamente manipulados y por lo tanto inútil. (2) Incluso Almohada docs estado que:

Acceder a cada uno de los píxeles es bastante lento. Si usted es un bucle a través de todos >los píxeles de una imagen, es probable que de una manera más rápida el uso de otras piezas de >la Almohada de la API.

  • Cuando ejecuto el código en mi máquina, data es una lista de regular enteros.
  • La documentación puede estar refiriéndose a getdata, que espero es más rápido que por píxel de acceso.
  • No estoy al tanto de cualquier librerías de Python que no están lento con el píxel individual de acceso.
InformationsquelleAutor Armin | 2016-11-21

2 Kommentare

  1. 11

    Puede convertir los datos de imagen en una lista de Python (o lista de listas) como este:

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

    Aquí es una versión ampliada de un pequeño 24×24 RGB huevos.png imagen que he usado para las pruebas:

    Cómo convertir una imagen en escala de grises en una lista de valores de píxeles?

    Aquí está el resultado desde el primer ejemplo de acceso:

    Cómo convertir una imagen en escala de grises en una lista de valores de píxeles?

    Y aquí el resultado del segundo ejemplo:

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

    El acceso a los datos de píxeles ahora debería ser más rápido que usando el objeto img.load() devuelve (y los valores enteros en el rango de 0..255).

  2. 1

    Puede acceder a la escala de grises valor de cada píxel individual mediante el acceso a la r, g o b valor, que va a ser la misma para una imagen en escala de grises.

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

    Esto no resuelve el problema de la velocidad de acceso.

    Estoy más familiarizado con scikit-imagen de la Almohada. A mí me parece que si todo lo que está después es el listado de los valores de escala de grises, puede utilizar scikit-imagen, que almacena las imágenes como arrays de numpy, y el uso img_as_ubyte para representar la imagen como un valor de este tipo de matriz, que contiene valores entre 0 y 255.

    Las imágenes son Arrays de NumPy proporciona un buen punto de partida para ver el aspecto del código.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea