How to convert a PIL Image into a numpy array?

后端 未结 8 2237
不知归路
不知归路 2020-11-22 17:12

Alright, I\'m toying around with converting a PIL image object back and forth to a numpy array so I can do some faster pixel by pixel transformations than PIL\'s Pixel

相关标签:
8条回答
  • 2020-11-22 17:26

    Convert Numpy to PIL image and PIL to Numpy

    import numpy as np
    from PIL import Image
    
    def pilToNumpy(img):
        return np.array(img)
    
    def NumpyToPil(img):
        return Image.fromarray(img)
    
    0 讨论(0)
  • 2020-11-22 17:31

    If your image is stored in a Blob format (i.e. in a database) you can use the same technique explained by Billal Begueradj to convert your image from Blobs to a byte array.

    In my case, I needed my images where stored in a blob column in a db table:

    def select_all_X_values(conn):
        cur = conn.cursor()
        cur.execute("SELECT ImageData from PiecesTable")    
        rows = cur.fetchall()    
        return rows
    

    I then created a helper function to change my dataset into 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
    

    After this, I was able to use the byteArrays in my Neural Network.

    plt.imshow(imagesList[0])
    
    0 讨论(0)
  • 2020-11-22 17:33

    The example, I have used today:

    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)
    
    0 讨论(0)
  • 2020-11-22 17:34

    I am using Pillow 4.1.1 (the successor of PIL) in Python 3.5. The conversion between Pillow and numpy is straightforward.

    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)
    

    One thing that needs noticing is that Pillow-style im is column-major while numpy-style im2arr is row-major. However, the function Image.fromarray already takes this into consideration. That is, arr2im.size == im.size and arr2im.mode == im.mode in the above example.

    We should take care of the HxWxC data format when processing the transformed numpy arrays, e.g. do the transform im2arr = np.rollaxis(im2arr, 2, 0) or im2arr = np.transpose(im2arr, (2, 0, 1)) into CxHxW format.

    0 讨论(0)
  • 2020-11-22 17:37

    You're not saying how exactly putdata() is not behaving. I'm assuming you're doing

    >>> 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
    

    This is because putdata expects a sequence of tuples and you're giving it a numpy array. This

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

    will work but it is very slow.

    As of PIL 1.1.6, the "proper" way to convert between images and numpy arrays is simply

    >>> pix = numpy.array(pic)
    

    although the resulting array is in a different format than yours (3-d array or rows/columns/rgb in this case).

    Then, after you make your changes to the array, you should be able to do either pic.putdata(pix) or create a new image with Image.fromarray(pix).

    0 讨论(0)
  • 2020-11-22 17:42

    Open I as an array:

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

    Do some stuff to I, then, convert it back to an image:

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

    Filter numpy images with FFT, Python

    If you want to do it explicitly for some reason, there are pil2array() and array2pil() functions using getdata() on this page in correlation.zip.

    0 讨论(0)
提交回复
热议问题