Sree
Sree

Reputation: 983

How to store a 2D array with values from 0-20 to a grayscale image in python

I am working on an image segmentation project and I have a 2D array of size (224,224) with the values from 0-20 with each number representing a category of the dataset. I want to store this 2D array to a grayscale image and read it back with the same 0-20 values. I couldn't find a proper way to do this. I tried as below but although it's storing as a grayscale image, I couldn't read back the actual 2D array when reading the array from the image.

#arr is the 2D array of size (224,224) with values from 0-20     
rescaled = (255.0 / arr.max() * (arr - arr.min())).astype(np.uint8)
img = PIL.Image.fromarray(rescaled)
img.save(filename)

But when I read it back I = np.asarray(PIL.Image.open('filename.png')) I could only see 0's and 255. I need the values with 0-20. How can I do this? I tried to do it with cv2.imwrite(filename,arr) but all it gave is a blank image.

Upvotes: 0

Views: 188

Answers (1)

Peter Lee
Peter Lee

Reputation: 381

You can try the below code

#arr is the 2D array of size (224,224) with values from 0-20     
min_value = arr.min()
max_Value = arr.max()
rescaled = (255.0 // (max_Value-min_value)  * (arr - min_value)).astype(np.uint8)
img = Image.fromarray(rescaled)
img.save(img_name, "BMP")

import_array = np.asarray(Image.open(img_name), dtype="int32")
rescaled_import_img = min_value + import_array*(max_Value- min_value)//255 
print (rescaled_import_img)

There is a problem with approximation. When you divide integer value, the result would be float and be rounded. When you load values there would be difference. We'd better to not scale values but keep 0-20 values in the gray image and load them later.

Update 1

Without rescale

img = Image.fromarray(np.uint8(arr))
img.save(img_name, "BMP")
print (img)

import_array = np.array(Image.open(img_name), dtype="uint8")
print (import_array)

Upvotes: 1

Related Questions