Вопрос:

Как преобразовать изображение PIL в массив Numpy?

python image numpy python-imaging-library

242608 просмотра

6 ответа

12448 Репутация автора

Хорошо, я играю с преобразованием объекта изображения PIL взад-вперед в массив, чтобы я мог сделать более быстрое преобразование пикселей за пикселем, чем PixelAccessпозволил бы объект PIL . Я выяснил, как разместить информацию о пикселях в полезном трехмерном массиве с помощью:

pic = Image.open("foo.jpg")
pix = numpy.array(pic.getdata()).reshape(pic.size[0], pic.size[1], 3)

Но я не могу понять, как загрузить его обратно в объект PIL после того, как я выполнил все свои потрясающие преобразования. Я знаю о putdata()методе, но не могу заставить его вести себя.

Автор: akdom Источник Размещён: 21.12.2008 06:21

Ответы (6)


189 плюса

52375 Репутация автора

Решение

Вы не говорите, как именно putdata()не ведет себя. Я предполагаю, что вы делаете

>>> pic.putdata(a)
Traceback (most recent call last):
  File "...blablabla.../PIL/Image.py", line 1185, in putdata
    self.im.putdata(data, scale, offset)
SystemError: new style getargs format but argument is not a tuple

Это потому, что putdataожидает последовательность кортежей, а вы присваиваете ей пустой массив. это

>>> data = list(tuple(pixel) for pixel in pix)
>>> pic.putdata(data)

будет работать, но это очень медленно.

Начиная с PIL 1.1.6, «правильный» способ преобразования между изображениями и массивами просто

>>> pix = numpy.array(pic)

хотя результирующий массив имеет другой формат, чем ваш (в этом случае 3-й массив или row / columns / rgb).

Затем, после того, как вы внесете изменения в массив, вы сможете сделать то же самое pic.putdata(pix)или создать новое изображение с помощью Image.fromarray(pix).

Автор: dF. Размещён: 21.12.2008 08:46

136 плюса

10744 Репутация автора

Открыть Iкак массив:

>>> I = numpy.asarray(PIL.Image.open('test.jpg'))

Сделайте некоторые вещи, чтобы Iзатем преобразовать их обратно в изображение:

>>> im = PIL.Image.fromarray(numpy.uint8(I))

Фильтрация изображений с помощью FFT, Python

Если вы хотите сделать это явно по какой-то причине, есть функции pil2array () и array2pil (), использующие getdata () на этой странице в correlation.zip.

Автор: endolith Размещён: 08.07.2009 02:33

9 плюса

5908 Репутация автора

Вам нужно преобразовать ваше изображение в массив numy следующим образом:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 
Автор: Billal Begueradj Размещён: 07.06.2016 09:18

3 плюса

304 Репутация автора

Пример, который я использовал сегодня:

import PIL
import numpy
from PIL import Image

def resize_image(numpy_array_image, new_height):
    # convert nympy array image to PIL.Image
    image = Image.fromarray(numpy.uint8(numpy_array_image))
    old_width = float(image.size[0])
    old_height = float(image.size[1])
    ratio = float( new_height / old_height)
    new_width = int(old_width * ratio)
    image = image.resize((new_width, new_height), PIL.Image.ANTIALIAS)
    # convert PIL.Image into nympy array back again
    return array(image)
Автор: Uki D. Lucas Размещён: 03.02.2017 08:32

43 плюса

981 Репутация автора

Я использую подушку 4.1.1 (преемник PIL) в Python 3.5. Преобразование между Подушкой и NumPy является простым.

from PIL import Image
import numpy as np
im = Image.open('1.jpg')
im2arr = np.array(im) # im2arr.shape: height x width x channel
arr2im = Image.fromarray(im2arr)

Одна вещь, на которую нужно обратить внимание, - это то, что стиль подушек im- основной столбец, в то время как стиль numpy im2arr- основной ряд. Однако функция Image.fromarrayуже принимает это во внимание. То есть arr2im.size == im.sizeи arr2im.mode == im.modeв приведенном выше примере.

Мы должны позаботиться о формате данных HxWxC при обработке преобразованных числовых массивов, например, выполнить преобразование im2arr = np.rollaxis(im2arr, 2, 0)или im2arr = np.transpose(im2arr, (2, 0, 1))в формат CxHxW.

Автор: Daniel Размещён: 17.06.2017 04:41

0 плюса

11 Репутация автора

Если ваше изображение хранится в формате Blob (то есть в базе данных), вы можете использовать ту же технику, которая была объяснена Биллом Бегераджем, чтобы преобразовать ваше изображение из BLOB-объектов в байтовый массив.

В моем случае мне понадобились мои изображения, которые хранятся в столбце BLOB-объектов в таблице БД:

def select_all_X_values(conn):
    cur = conn.cursor()
    cur.execute("SELECT ImageData from PiecesTable")    
    rows = cur.fetchall()    
    return rows

Затем я создал вспомогательную функцию для изменения набора данных в np.array:

X_dataset = select_all_X_values(conn)
imagesList = convertToByteIO(np.array(X_dataset))

def convertToByteIO(imagesArray):
    """
    # Converts an array of images into an array of Bytes
    """
    imagesList = []

    for i in range(len(imagesArray)):  
        img = Image.open(BytesIO(imagesArray[i])).convert("RGB")
        imagesList.insert(i, np.array(img))

    return imagesList

После этого я смог использовать byteArrays в моей нейронной сети.

plt.imshow(imagesList[0])
Автор: Charles Vogt Размещён: 15.02.2019 07:00
Вопросы из категории :
32x32