I am saving images using
import matplotlib.pyplot as plt
plt.imsave(img_path,img_arr,cmap = 'gray') #shape (512,512)
...
img = plt.imread(img_path)
and the img.shape returns a (512,512,4) whereas i expect it to only be (512,512).
I thought maybe all the channels would be the same so I could just pick one but np.allclose(img[:,:,0],img_arr)
returns false no matter which index I choose. Printing the images, they are indeed the correct ones I am comparing as they do look almost identical(by eye), but are obviously not exactly identical.
I also tried saving the images with cv2 but that seems to save a black box for some reason. loading them with cv2.imread(img_path,0)
does return a (512,512) array but something seems to be lost because again, np.allclose()
tells me they're different.
I wanted to know if there is a good way to save grayscale images? Every method I try seems to convert it to RBG or RGBA which is really annoying. Also, I would like to preserve the dtype (int16) of the image as downsampling it loses important information.
Thanks in advance.
You cannot preserve a bit depth of 16 bit when saving images with matplotlib with any of the default colormaps which only have 256 colors (=8 bit).
And in addition, matplotlib converts the pixel values to floats, which may be a source for rounding errors.
In total, matplotlib does not seem to be the optimal tool in case you need to get perfect accuracy.
That being said, even PIL
does not seem to allow for 16 bit single channel pngs. There is a possible solution in this question, but I haven't tested it.
In any case a bulletproof way to save your array without accuracy loss is to save it with numpy, np.save("arr.npy", im_arr)
.
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