Изображение 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:
GetDatap >
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()