プレーン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配列に変換するにはどうすればよいですか?
あなたが探しているものは次のとおりです:
list(im.getdata())
または、画像が大きすぎてメモリに完全にロードできない場合、次のようになります。
for pixel in iter(im.getdata()):
print pixel
from PIL documentation :
getdata
im.getdata()=>シーケンス
画像の内容をピクセル値を含むシーケンスオブジェクトとして返します。シーケンスオブジェクトはフラット化されているため、1行目の値は0行目の値の直後に続きます。
このメソッドによって返されるシーケンスオブジェクトは内部PILデータ型であり、反復や基本的なシーケンスアクセスを含む特定のシーケンス操作のみをサポートすることに注意してください。それを通常のシーケンスに変換するには(たとえば、印刷用)、list(im.getdata())を使用します。
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
`` `
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
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()