Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert dtype(uint16) data into a 16bit png image?

I'm trying to encrypt and decrypt an image using RSA algo. For that, I need to read the image as greyscale and then apply the keys and save the uint16 type array into a png or any image format which supports 16bit data. Then I need to read that 16bit data convert it into an array and do the decryption. Now, previously I tried to save the image as .tif and when I read it with

img = sk.imread('image.tiff', plugin = 'tifffile')

it treats the image as RGB, which is not what I want. Now I want to save the uint16 type array to a 16bit png image which will take values between 0 to 65536 and then read it again as a uint16 type data. I tried to save the values to a 16bit png file using

img16 = img.astype(np.uint16)
imgOut = Image.fromarray(img16)
imgOut.save('en.png')

This gives me this error: OSError: cannot write mode I;16 as PNG

I have also tried imgOut = Image.fromarray(img16, 'I') but this yeilds not enough image data

Please help me to save the 16bit data into a .png image. Thank you.

like image 734
Dutta Avatar asked Mar 23 '19 08:03

Dutta


1 Answers

There are a couple of possibilities...

First, using imageio to write a 16-bit PNG:

import imageio
import numpy as np

# Construct 16-bit gradient greyscale image
im = np.arange(65536,dtype=np.uint16).reshape(256,256)

# Save as PNG with imageio
imageio.imwrite('result.png',im) 

You can then read the image back from disk and change the first pixel to mid-grey (32768) like this:

# Now read image back from disk into Numpy array
im2 = imageio.imread('result.png') 

# Change first pixel to mid-grey
im2[0][0] = 32768

Or, if you don't like imageio, you can use PIL/Pillow and save a 16-bit TIFF:

from PIL import Image
import numpy as np

# Construct 16-bit gradient greyscale image
im = np.arange(65536,dtype=np.uint16).reshape(256,256)

# Save as TIFF with PIL/Pillow
Image.fromarray(im).save('result.tif')

You can then read back the image from disk and change the first pixel to mid-grey like this:

# Read image back from disk into PIL Image
im2 = Image.open('result.tif')                                                                                             

# Convert PIL Image to Numpy array
im2 = np.array(im2)

# Make first pixel mid-grey
im2[0][0] = 32768

enter image description here


Keywords: Image, image processing, Python, Numpy, PIL, Pillow, imageio, TIF, TIFF, PNG, 16 bit, 16-bit, short, unsigned short, save, write.

like image 108
Mark Setchell Avatar answered Oct 02 '22 05:10

Mark Setchell