0

I want to apply a plt colormap to a medical grayscale image (14bit (16383 is the maximum pixel value) image stored as np.uint16) and save it as a single channel grayscale image. However when I do:

import matplotlib.pyplot as plt
import numpy as np

rand_img = np.random.randint(low=0, high=16383,size=(500,500),dtype=np.uint16)
# rand_img.shape = (500,500)
cm = plt.cm.gist_yarg
norm = plt.Normalize(vmin=0, vmax=((2**14)-1))
img = cm(norm(rand_img))
# img.shape = (500,500,4)

the resulting img.shape is a 4 channel (rgba?) image whereas what I want is a one channel image. The first 3 channels are all the same so I could just slice out one channel and use it. However the image turns out significantly darker as when I display it with, e.g.,

plt.imshow(rand_img, cmap=plt.cm.gist_yarg)

So how can I apply the colormap and save the image so that it looks exactly like when I use plt.imshow?

PS: When I use plt.imsave with the colormap the saved image looks as expected, however it is still stores as a 4 channel image and not as a single channel image.

Kaschi14
  • 116
  • 5

1 Answers1

0

I am almost certain that the difference you are seeing is coming from the default dpi setting in plt.savefig(). See this question for details. Since the default DPI is 100, it is likely that the difference you are seeing comes from down-sampling during image saving. Trying plt.savefig() with the default DPI setting on your example, I can clearly see that the fine details are missing.

Modifying your code slightly, I can take your example and get two reasonably close looking plots:

import matplotlib.pyplot as plt
import numpy as np

SAVEFIG_DPI = 1000
np.random.seed(1000)  # Added to make example repeatable

rand_img = np.random.randint(low=0, high=16383, size=(500, 500), dtype=np.uint16)
cm = plt.cm.gist_yarg
norm = plt.Normalize(vmin=0, vmax=((2**14) - 1))
norm_cm_img = cm(norm(rand_img))

plt.imshow(norm_cm_img)
plt.savefig("test.png", dpi = SAVEFIG_DPI)

plt.imshow(norm_cm_img)
plt.show()

I get the following output, with show() on the left, and the image file on the right:

enter image description here

It's worth noting that I did try using fig.dpi as suggested in the linked question, but I was not able to get results that looked as close as this using that approach.

rnorris
  • 1,571
  • 2
  • 17
  • 23