2

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.

EvGEN Levakov
  • 23
  • 1
  • 8
fgh
  • 169
  • 1
  • 3
  • 15

2 Answers2

1

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.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Very nice and simple answer, thank you. I didn't know about `np.array_equal`, but I will definitely like it. Indeed, I produce colour image, however my program doesn't predict the palette of colours of a given picture. It tests later whether it is coloured or gray and then adjusts the code to modify the image. If I used `convert('L')` method, I would operate only on grayscale pictures. Finally, once again - thank you! – fgh Apr 24 '19 at 16:19
  • Improves or doesn't improve - you deserve it. – fgh Apr 24 '19 at 16:27
0

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

AJ Bensman
  • 550
  • 4
  • 11