Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting 2D Numpy array of grayscale values to a PIL image

Say I have a 2D Numpy array of values on the range 0 to 1, which represents a grayscale image. How do I then convert this into a PIL Image object? All attempts so far have yielded extremely strange scattered pixels or black images.

for x in range(image.shape[0]):     for y in range(image.shape[1]):         image[y][x] = numpy.uint8(255 * (image[x][y] - min) / (max - min))  #Create a PIL image. img = Image.fromarray(image, 'L') 

In the code above, the numpy array image is normalized by (image[x][y] - min) / (max - min) so every value is on the range 0 to 1. Then it is multiplied by 255 and cast to an 8 bit integer. This should, in theory, process through Image.fromarray with mode L into a grayscale image - but the result is a set of scattered white pixels.

like image 382
Blake Doeren Avatar asked Jun 01 '16 02:06

Blake Doeren


People also ask

Is grayscale image 2D array?

Grayscale image, represented by a 2D array of numbers that are proportional to pixel brightness.

How do you save a grayscale image in PIL?

You can save the grayscale image using the save() method. The save() method stores the image in our filesystem.


2 Answers

I think the answer is wrong. The Image.fromarray( ____ , 'L') function seems to only work properly with an array of integers between 0 and 255. I use the np.uint8 function for this.

You can see this demonstrated if you try to make a gradient.

import numpy as np from PIL import Image  # gradient between 0 and 1 for 256*256 array = np.linspace(0,1,256*256)  # reshape to 2d mat = np.reshape(array,(256,256))  # Creates PIL image img = Image.fromarray(np.uint8(mat * 255) , 'L') img.show() 

Makes a clean gradient

vs

import numpy as np from PIL import Image  # gradient between 0 and 1 for 256*256 array = np.linspace(0,1,256*256)  # reshape to 2d mat = np.reshape(array,(256,256))  # Creates PIL image img = Image.fromarray( mat , 'L') img.show() 

Has the same kind of artifacting.

like image 73
Nathan Avatar answered Sep 17 '22 19:09

Nathan


If I understood you question, you want to get a grayscale image using PIL.

If this is the case, you do not need to multiply each pixels by 255.

The following worked for me

import numpy as np from PIL import Image  # Creates a random image 100*100 pixels mat = np.random.random((100,100))  # Creates PIL image img = Image.fromarray(mat, 'L') img.show() 
like image 38
lsxliron Avatar answered Sep 20 '22 19:09

lsxliron