fgh
fgh

Reputation: 199

Grayscale .png to numpy array

Indeed, this question has been answered many times. However, as I am not allowed to add a comment to an answer due to "too low" reputation, I would like to discuss the solution presented in the most comprehensive answer.

Wouldn't the solution:

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt #Used in the comparison below

im = Image.open('file.png').convert('RGB') #Opens a picture in grayscale
pic = np.array(im)
im.close()

work properly? I am wondering whether unacceptable changes in the quality occur. I have noticed some differences (i.e. black rows at the top in plt.imshow()) when I display the image:

im.show() #Before closing
plt.imshow(pic)

but I don't know whether they are only inevitable consequences of converting to np.array.

PS - If it is important, I would mention that I prepare the image for color quantization (KMeans) and Floyd dithering.

PPS - If you advised me how not to post duplicate question but discuss answers directly - it would be really appreciated.

Upvotes: 2

Views: 3803

Answers (2)

AJ Bensman
AJ Bensman

Reputation: 580

I was working on doing a similar thing, and I'm not sure why but I ran into a bunch of issues. In the end this worked for me pretty well without loss of any data.

from PIL import Image
import numpy as np
img=np.array(Image.open(filename).convert('L'))

and to convert back:

import imageio
array = array.astype(np.uint8)
imageio.imwrite(newfilename, array)

edit: this only works for black and white images. Color images need 3D arrays rather than 2D arrays

Upvotes: 0

Mark Setchell
Mark Setchell

Reputation: 207863

Try it and see!

from PIL import Image 
import numpy as np

# Other answer method
im1 = Image.open('gray.png').convert('L')
im1 = np.stack((im1,)*3, axis=-1)

# Your method
im2 = Image.open('gray.png').convert('RGB')                  
im2 = np.array(im2) 

# Test if identical
print(np.array_equal(im1,im2))

Sample Output

True

I would say the one aspect that is different, is that the method in the other answer will work (insofar as it actually makes a greyscale image where R=G=B) even if the input image is colour, whereas your method will produce a colour image.

Upvotes: 1

Related Questions