2012-11-25 191 views
11

我有一个.jpg图像,我想转换为Python数组,因为我实现了处理普通Python数组的处理例程。PIL图像阵列(numpy数组到阵列) - 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数组?

+2

你试过了numpy的阵列的'tolist()'方法? – joeln

回答

11

我知道你在寻找的是:

list(im.getdata()) 

或者,如果图像是太大了,完全加载到内存中,这样类似的东西:

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

PIL documentation

getdata

im.getdata()=>序列

返回图像的内容作为包含像素值 的序列对象。序列对象被平铺,因此第一行 的值紧跟在第零行的值之后,依此类推。

请注意,此方法返回的序列对象是一个内部的 PIL数据类型,它仅支持某些序列操作,包括迭代和基本序列访问在内的 。要将其转换为 普通序列(例如用于打印),请使用list(im.getdata())。

+0

在文档中看起来不错,但仍然无法正常工作。我不得不放弃过程。任何想法?谢谢 – octoback

+0

首先尝试使用较小的图像,只是为了看到您正在获得所需的结果,然后您可以处理因尝试将整个图像加载到列表中并将其打印出来而导致的内存问题。 – zenpoy

+0

我怎么能管理这些内存问题? – octoback

4

基于zenpoys回答:

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 
2

我用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() 
11

我强烈建议你使用Image对象的tobytes函数。经过一些时间检查后,这个效率会更高。

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 

```