Изображение PIL для массива (массив numpy для массива) - Python

У меня есть .jpg изображение, которое я хотел бы преобразовать в массив Python, потому что я реализовал процедуры обработки, обрабатывающие простые массивы Python.

Кажется, что изображения PIL поддерживают преобразование в массив numpy, и в соответствии с документацией я написал это:

from PIL import Image
im = Image.open("D:\Prototype\Bikesgray.jpg")
im.show()

print(list(np.asarray(im)))

Это возвращает список массивов numpy. Кроме того, я пробовал с помощью

list([list(x) for x in np.asarray(im)])

который ничего не возвращает, поскольку он терпит неудачу.

Как я могу преобразовать из PIL в массив или просто из массива numpy в массив Python?

Ответ 1

Я думаю, что вы ищете:

list(im.getdata())

или, если изображение слишком велико для полной загрузки в память, что-то вроде этого:

for pixel in iter(im.getdata()):
    print pixel

из Документация PIL:

GetData​​p >

im.getdata() = > последовательность

Возвращает содержимое изображения в виде объекта последовательности, содержащего пиксель значения. Объект последовательности сглаживается, так что значения для первой строки следуют сразу после значений нулевой линии и т.д.

Обратите внимание, что объект последовательности, возвращаемый этим методом, является внутренним PIL, который поддерживает только определенные операции последовательности, включая итерацию и доступ к базовой последовательности. Чтобы преобразовать его в обычную последовательность (например, для печати), используйте список (im.getdata()).

Ответ 2

Я настоятельно рекомендую вам использовать функцию tobytes объекта Image. После некоторых проверок времени это намного эффективнее.

def jpg_image_to_array(image_path):
  """
  Loads JPEG image into 3D Numpy array of shape 
  (width, height, channels)
  """
  with Image.open(image_path) as image:         
    im_arr = np.fromstring(image.tobytes(), dtype=np.uint8)
    im_arr = im_arr.reshape((image.size[1], image.size[0], 3))                                   
  return im_arr

Тайминги, которые я запускал на своем ноутбуке

In [76]: %timeit np.fromstring(im.tobytes(), dtype=np.uint8)
1000 loops, best of 3: 230 µs per loop

In [77]: %timeit np.array(im.getdata(), dtype=np.uint8)
10 loops, best of 3: 114 ms per loop

`` `

Ответ 3

Основываясь на ответе zenpoy:

import Image
import numpy

def image2pixelarray(filepath):
    """
    Parameters
    ----------
    filepath : str
        Path to an image file

    Returns
    -------
    list
        A list of lists which make it simple to access the greyscale value by
        im[y][x]
    """
    im = Image.open(filepath).convert('L')
    (width, height) = im.size
    greyscale_map = list(im.getdata())
    greyscale_map = numpy.array(greyscale_map)
    greyscale_map = greyscale_map.reshape((height, width))
    return greyscale_map

Ответ 4

Я использую numpy.fromiter для инвертирования растрового изображения с 8 оттенками серого, но никаких признаков побочных эффектов

import Image
import numpy as np

im = Image.load('foo.jpg')
im = im.convert('L')

arr = np.fromiter(iter(im.getdata()), np.uint8)
arr.resize(im.height, im.width)

arr ^= 0xFF  # invert
inverted_im = Image.fromarray(arr, mode='L')
inverted_im.show()