PIL图像到数组(numpy数组到数组) - Python

时间:2022-04-12 18:18:13

I have a .jpg image that I would like to convert to Python array, because I implemented treatment routines handling plain Python arrays.

我有一个.jpg图像,我想转换为Python数组,因为我实现了处理普通Python数组的处理例程。

It seems that PIL images support conversion to numpy array, and according to the documentation I have written this:

似乎PIL图像支持转换为numpy数组,并且根据我写的文档:

from PIL import Image
im = Image.open("D:\Prototype\Bikesgray.jpg")
im.show()

print(list(np.asarray(im)))

This is returning a list of numpy arrays. Also, I tried with

这将返回一个numpy数组列表。另外,我尝试过

list([list(x) for x in np.asarray(im)])

which is returning nothing at all since it is failing.

因为它失败了,它什么都没有返回。

How can I convert from PIL to array, or simply from numpy array to Python array?

如何从PIL转换为数组,或者简单地从numpy数组转换为Python数组?

4 个解决方案

#1


11  

I think what you are looking for is:

我认为你在寻找的是:

list(im.getdata())

or, if the image is too big to load entirely into memory, so something like that:

或者,如果图像太大而无法完全加载到内存中,那么类似的东西:

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

from PIL documentation:

来自PIL文档:

getdata

的GetData

im.getdata() => sequence

im.getdata()=>序列

Returns the contents of an image as a sequence object containing pixel values. The sequence object is flattened, so that values for line one follow directly after the values of line zero, and so on.

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

Note that the sequence object returned by this method is an internal PIL data type, which only supports certain sequence operations, including iteration and basic sequence access. To convert it to an ordinary sequence (e.g. for printing), use list(im.getdata()).

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

#2


13  

I highly recommend you use the tobytes function of the Image object. After some timing checks this is much more efficient.

我强烈建议您使用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

The timings I ran on my laptop show

我在笔记本电脑上播放的时间显示

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

```

```

#3


5  

Based on zenpoy's answer:

根据zenpoy的回答:

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

#4


2  

I use numpy.fromiter to invert a 8-greyscale bitmap, yet no signs of side-effects

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

#1


11  

I think what you are looking for is:

我认为你在寻找的是:

list(im.getdata())

or, if the image is too big to load entirely into memory, so something like that:

或者,如果图像太大而无法完全加载到内存中,那么类似的东西:

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

from PIL documentation:

来自PIL文档:

getdata

的GetData

im.getdata() => sequence

im.getdata()=>序列

Returns the contents of an image as a sequence object containing pixel values. The sequence object is flattened, so that values for line one follow directly after the values of line zero, and so on.

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

Note that the sequence object returned by this method is an internal PIL data type, which only supports certain sequence operations, including iteration and basic sequence access. To convert it to an ordinary sequence (e.g. for printing), use list(im.getdata()).

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

#2


13  

I highly recommend you use the tobytes function of the Image object. After some timing checks this is much more efficient.

我强烈建议您使用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

The timings I ran on my laptop show

我在笔记本电脑上播放的时间显示

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

```

```

#3


5  

Based on zenpoy's answer:

根据zenpoy的回答:

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

#4


2  

I use numpy.fromiter to invert a 8-greyscale bitmap, yet no signs of side-effects

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