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).
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.
Grayscale image, represented by a 2D array of numbers that are proportional to pixel brightness.
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.
You need a lossless image format that can save floats:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With