I have some images in some range of numbers. Here's an example of an image:
This is a level in a Laplacian Pyramid of an image. (It's not necessary to understand what a Laplacian Pyramid is...)
Now I need to make some operations on those images, and I need to change the colormap for that. I changed it to gray(256) and made the operations i need. So now I have different images in
Now I need to scale back to the previous range. But I don't know the previous range or colormap. I tried saving the colormap before the operations.
I tried this:
but that changed the whole matrix to 255.
What's the right way to do it?
colormap only sets the color of a
figure, so you don't need it in
imwrite. In fact, it does nothing of value here. If you pass a map,
gray(256), it will write this as an indexed image. That is, it saves in the file both the values of the pixels and the map which says what those values mean.
However, it doesn't scale the input image to match the colormap neatly. As stated in the docs:
If A is an indexed image of data type double or single, then imwrite converts the indices to zero-based indices by subtracting 1 from each element, and then writes the data as uint8. If the data in A is single, convert A to double before writing to a GIF or TIFF file.
What this means is if your
img contains all values of 256 or above,
imwrite will subtract one, and write as
uint8, clipping values over 255 to 255 (and below 0 to 0). So your image appears as all 255.
You need to first scale
img to an appropriate range (e.g. record the max and min values of your input matrix - not the
colormap! - before you do anything to it). This is just math - e.g. something like
img = img/256 may be all you need. It is unnecessary to save it with a map in most cases - you're just writing your values as grayscale, you can save them with
imwrite into a normal image.
imwrite generally expects
double to be in the range of 0 to 1 and
uint8 in the range of 0 to 255. If your values don't match up to this, you will get clipping/"blank" images, etc.
However, because values are stored as integers (
uint8) in most image formats, I don't see how you can use
imwrite to save the sort of values you display in your example without losing precision. You also won't be able to save any negative values. So it would be best to save your real values in a different format (
*.mat file, csv, etc.) and save an image if you need it for visualisation, but not for storing calculated values.