web-dev-qa-db-ja.com

PILイメージから配列(numpy array to array)-Python

プレーンPython配列を処理する処理ルーチンを実装したため、Python配列に変換したい.jpgイメージがあります。

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配列に変換するにはどうすればよいですか?

19
kiriloff

あなたが探しているものは次のとおりです:

list(im.getdata())

または、画像が大きすぎてメモリに完全にロードできない場合、次のようになります。

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

from PIL documentation

getdata

im.getdata()=>シーケンス

画像の内容をピクセル値を含むシーケンスオブジェクトとして返します。シーケンスオブジェクトはフラット化されているため、1行目の値は0行目の値の直後に続きます。

このメソッドによって返されるシーケンスオブジェクトは内部PILデータ型であり、反復や基本的なシーケンスアクセスを含む特定のシーケンス操作のみをサポートすることに注意してください。それを通常のシーケンスに変換するには(たとえば、印刷用)、list(im.getdata())を使用します。

15
zenpoy

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

`` `

17
awnihannun

zenpoy's answer に基づく:

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
6
Martin Thoma

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()
2
ccspeedup