Skip to content Skip to sidebar Skip to footer

When Converting An Image Into An Array And Viceversa, Are There Extra Considerations One Must Take Into Account?

I wrote this code to switch the red and blue values in the RGB array from a given image: from PIL import Image import numpy as np image = Image.open('image.jpg') RGBarr = np.asa

Solution 1:

The error occurs, when you try to read images which are not RGB like grayscale images or RGBA images. To keep the rest of your code valid, the easiest way would be to enforce RGB input by using:

image = Image.open("image.jpg").convert('RGB')

Then, possible grayscale or RGBA images are converted to RGB, and can be processed as regular RGB images.

As you found out yourself,

inv_image = Image.fromarray(newRGB)

also works, but the processing from the rest of your code then isn't correct anymore (no proper slicing of the desired dimensions/axes). That would require further work on your code to also respect grayscale or RGBA images.

Hope that helps!


EDIT: To incorporate furas' idea to get rid of NumPy, here's a PIL only way of swapping the channels. Notice: You still need the enforced RGB input.

from PIL import Image

image = Image.open('image.jpg').convert('RGB')

r, g, b = image.split()

inv_image = Image.merge('RGB', (b, g, r))

inv_image.save('inv_image.png')

inv_image.show()

Solution 2:

If you want to re-order RGB channels to BGR with Numpy, it is much simpler to do this:

BGR = RGB[...,::-1]

which just addresses the last index (i.e. the channels) in reverse. It has the benefit of being O(1) which means it takes the same amount of time regardless of the size of the array. On my Mac, it takes 180ns to do BGR->RGB with 10x10 image and just the same with a 10,000x10,000 image.


In general, you may want some other ordering rather than straight reversal, so if you want BGR->BRG, you can do:

BRG = BGR[...,(0,2,1)]

Or, if you want to make a 3-channel greyscale image by repeating the Green channel three times (because the green is usually the least noisy - see Wikipedia Bayer array article), you can simply do this:

RGBgrey = BGR[...,(1,1,1)]

If you want to get rid of Numpy, you can do it straight in PIL/Pillow using a matrix multiplication:

# Open image
im = Image.open('image.jpg')

# Define matrix to re-order RGB->BGR
Matrix = ( 0, 0, 1, 0,  
           0, 1, 0, 0,  
           1, 0, 0, 0)

# BGR -> RGB
BGR = im.convert("RGB", Matrix)

You can understand the matrix like this:

newR = 0*oldR + 0*oldG + 1*oldB + 0offset
newG = 0*oldR + 1*oldG + 0*oldB + 0offset
newB = 1*oldR + 0*oldG + 0*oldB + 0offset

Input

enter image description here

Result

enter image description here

Post a Comment for "When Converting An Image Into An Array And Viceversa, Are There Extra Considerations One Must Take Into Account?"