Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save 2D float numpy arrays losslessly into a grayscale image while preserving resolution?

Tags:

python

image

I have some Temperature field values which I want to convert to grayscale Image while preserving the resolution. (For example, if it's a (100x100) size float array, then the conversion should be a grayscale (100x100) image).Then I will process the image and convert it back to Temperature numpy array. The image processing part can be considered as a black-box process.

It's important that the conversion is lossless.

Also, the code for the image processing will recognise .png & .jpg. ( I am not sure about recognition of other file formats including tiff. Also, even jpg formats are not preferred since they will result in lossy conversion).

My attempts so far:

  • Matplotlib's imsave() is resolution preserving and is lossless. But it converts the image into RGB instead of grayscale. This approach is also fine with me, but I am unable to accurately convert the 3 channel RGB image back to float numpy array. For example, I took a 10x10 numpy float array temperature, used plt.imsave('Temperature_profile.png',temperature). Then, I reopened the same image but am unable to find out an accurate way to transform it back to (10x10) float array. So, the problem is solved if there is a way to convert back 3 channel image to 2D matrix losslessly.

  • PIL's Image.fromarray() preserves resolution and can save image as a grayscale image. But I unable to save the matrix losslessly and retrieve it back losslessly. Hence I will get wrong results. (Converting 2D Numpy array of grayscale values to a PIL image)

  • scipy.misc.imsave() has deprecated.

  • imageio.imwrite() gives a warning about lossy conversion. ("Lossy conversion from float64 to uint8").

  • opencv and cv2 for some reason is not getting recognised by my spyder environment (python 3.7,Anaconda 4.7.12).

like image 792
Bharath Ram Avatar asked Sep 30 '19 15:09

Bharath Ram


People also ask

How do I save a NumPy array as a picture?

Create a sample Numpy array and convert the array to PIL format using fromarray() function of PIL. This will open a new terminal window where the image will be displayed. To save the Numpy array as a local image, use the save() function and pass the image filename with the directory where to save it.

Is grayscale image 2D array?

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

How do I convert RGB array to grayscale?

Use numpy. dot() to convert an image from RGB to grayscale imread(fname) to get a NumPy array representing an image named fname . Call numpy. dot(a, b) with a as array[...,:3] and b as [0.2989, 0.5870, 0.1140] to convert the previous result array to grayscale.


1 Answers

You need a lossless image format that can save floats:

  • PNG can only save up to 16-bit integer,
  • JPEG is not lossless and only 8-bit integer,
  • GIF is integer and 8-bit,
  • NetPBM is up to 16-bit integer only.

so use TIFF with lossless compression, or no compression. Alternatively you could use PFM - Portable Float Map.


Here is a demonstration:

import numpy as np
from PIL import Image

# Generate a small float image in Numpy array
grey32 = np.random.randn(2,3).astype(np.float32)                                           

# Convert to PIL Image and save
Image.fromarray(grey32).save('test.tif')                                                   

# Read back from disk and convert to Numpy array
reloaded = np.array(Image.open('test.tif'))                                                

# Inspect
print(grey32)

array([[-0.28032717, -1.7696048 , -0.9811929 ],
       [-0.7785768 , -1.2427857 , -0.33241433]], dtype=float32)

print(reloaded)                                                                           

array([[-0.28032717, -1.7696048 , -0.9811929 ],
       [-0.7785768 , -1.2427857 , -0.33241433]], dtype=float32)

If your viewer is incapable of showing TIFF files containing floats, you can always convert them to something viewable with ImageMagick:

magick float.tif -auto-level viewable.png

I know that tifffile and pyvips are both good Python libraries for dealing with TIFF floats.

like image 54
Mark Setchell Avatar answered Oct 19 '22 03:10

Mark Setchell