Search code examples
pythonmatplotlibrgbrgbascikit-image

Image converted by skimage.color rgba to rgb is saved as rgba by matplotlib imsave


I need to convert a PNG H*W*4 rgba image to rgb image with shape H*W*3.

Which I am able to do but when I save it the image is saved again as H*W*4 Here is the code snippet:

for idx, image in enumerate(image_names):
    #matplotlib as mpi here I use plt for plotting and mpi for read
    rgba = mpi.imread(os.path.join(read_path,image))
    #convert to rgb using skimage.color as rtl,
    rgb = rtl.rgba2rgb(rgba)
    #change path of the image to be saved
    resized_path = os.path.join(os.path.sep,Ims,p[0],image)
    print(np.shape(rgb))#shape is printed (136,136,3)
    mpi.imsave(resized_path,rgb)

After this when I read it again its shape is again H*W*4 any Idea why? Is there anything with matplotlib imsave I guess?

Reference Image:

enter image description here

EDIT UPDATED CODE like this:

for idx, image in enumerate(image_names):
    rgba = plt.imread(os.path.join(read_path,image))
    rgb = skimage.color.rgba2rgb(rgba)
    #original image name do not have ext and adding or removing 
    # does not effect
    resized_path = os.path.join(os.path.sep,basepath,image,".png")
    rgb = Image.fromarray((rgb*255).astype(np.uint8))
    rgb.save(resized_path)

Got Following error:

    ValueError                                Traceback (most recent call last)
<ipython-input-12-648b9979b4e9> in <module>()
      6         print(np.shape(rgb))
      7         rgb = Image.fromarray((rgb*255).astype(np.uint8))
----> 8         rgb.save(resized_path)
      9     #mpi.imsave(resized_path,rgb)

/usr/local/lib/python2.7/dist-packages/PIL/Image.pyc in save(self, fp, format, **params)
   1809                 format = EXTENSION[ext]
   1810             except KeyError:
-> 1811                 raise ValueError('unknown file extension: {}'.format(ext))
   1812 
   1813         if format.upper() not in SAVE:

ValueError: unknown file extension:

Solution Solved answer below is correct the only problem above was resized path and here goes the change:

resized_path = os.path.join(os.path.sep,Ims,p[0],image)
resized_path = (resized_path+".png")

Solution

  • Matplotlib pyplot.imsave saves the image with an alpha channel (i.e. as RGBA) independend on whether or not the input array has such a channel present.

    However, there is no loss of information, since all alpha values are 1. Hence you can get your RGB image as

    new_im = plt.imread("image.png")[:,:,:3]
    # new_im.shape will be (<y>, <x>, 3)
    

    If you specifically need a RGB png image you need to use a different means to save the image.

    E.g. using PIL

    from PIL import Image
    import numpy as np
    import matplotlib.pyplot as plt
    
    im = np.random.rand(120,120,3)
    
    im2 = Image.fromarray((im*255).astype(np.uint8))
    im2.save("image2.png")
    
    new_im = plt.imread("image2.png")  
    print (new_im.shape)
    # prints  (120L, 120L, 3L)