web-dev-qa-db-ja.com

PILイメージをnumpy配列に変換する方法は?

さて、PILのPixelAccessオブジェクトが許可するよりも高速なピクセルごとの変換を行うことができるように、PIL画像オブジェクトをnumpy配列に前後に変換することに取り組んでいます。ピクセル情報を便利な3D numpy配列に配置する方法を見つけました。

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

しかし、すばらしい変換をすべて行った後、PILオブジェクトにロードする方法を理解することはできないようです。 putdata()メソッドは知っていますが、動作するようには思えません。

178
akdom

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が一連のタプルを想定しており、numpy配列を与えているためです。この

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

動作しますが、非常に遅いです。

PIL 1.1.6の時点では、イメージとnumpy配列の間で変換する 「適切な」方法 は単純です

>>> pix = numpy.array(pic)

ただし、結果の配列はユーザ​​ーの配列とは異なる形式(この場合は3次元配列またはrows/columns/rgb)です。

次に、配列に変更を加えた後、pic.putdata(pix)を実行するか、Image.fromarray(pix)を使用して新しいイメージを作成できます。

214
dF.

Iを配列として開きます。

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

Iにいくつかのことを行ってから、それをイメージに変換します。

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

FFT、Pythonでnumpyイメージをフィルター処理する

何らかの理由で明示的に実行したい場合、相関関係.Zipの このページ でgetdata()を使用するpil2array()およびarray2pil()関数があります。

150
endolith

Python 3.5でPillow 4.1.1(PILの後継)を使用しています。 Pillowと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)

気づく必要があることの1つは、ピロースタイルのimが列優先で、numpyスタイルのim2arrが行優先であることです。ただし、関数Image.fromarrayはすでにこれを考慮しています。つまり、上記の例のarr2im.size == im.sizeおよびarr2im.mode == im.modeです。

変換されたnumpy配列を処理するときは、HxWxCデータ形式に注意する必要があります。 im2arr = np.rollaxis(im2arr, 2, 0)またはim2arr = np.transpose(im2arr, (2, 0, 1))をCxHxW形式に変換します。

46
Daniel

この方法で画像をnumpy配列に変換する必要があります:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 
11

例は、私が今日使用しています:

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)
3
Uki D. Lucas

画像がBlob形式(つまり、データベース)に保存されている場合、Billal Begueradjが説明したのと同じ手法を使用して、Blobからバイト配列に画像を変換できます。

私の場合、dbテーブルの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])
0
Charles Vogt
def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

画像をnumpyに変換するには、機能を削除した後、画像をnumpy()関数に解析します(非正規化)

0
Thiyagu