# How can convert a image from type of double(unit16) to a grayscale image?

34 views (last 30 days)
Akshit on 23 Jan 2015
Edited: DGM on 17 Nov 2021 at 11:23
How can convert a image from type of double(unit16) to a grayscale image?

Shoaibur Rahman on 23 Jan 2015
ImageGray = mat2gray(ImageDouble);

DGM on 17 Nov 2021 at 10:41
Edited: DGM on 17 Nov 2021 at 11:23
The problem here isn't necessarily that the image isn't grayscale; it's that the data isn't scaled properly for other tools to know what to do with it. Consider the scenario where you have a uint16 image cast as double(), but not rescaled.
A0 = im2uint16(imread('cameraman.tif')); % uint16 image
A = double(A0); % now cast as double without rescaling
imshow(A) % show it
It doesn't show up against this awful white website background, but there's a totally white image there. Tools like imwrite and imshow expect data to be scaled within a specific range dependent on the class of the data. For uint16, black is 0, white is 65535; for floating-point classes, black is 0, white is 1. Since all of the data is >1, imshow treats it as white.
[min(A(:)) max(A(:))] % note that data does not span the entire [0 65535] range
ans = 1×2
1799 65021
If viewing this denormalized image is all that's needed, you can do this
imshow(A,[0 65535])
to explicitly specify the display mapping without changing the image.
Fixing the image
You could use mat2gray() to normalize the image, but that will normalize the image to its extreme values, altering the contrast of the image. The image which once contained neither black nor white has been stretched so that it does. This may be of no consequence if it's for viewing, but it may otherwise be an unacceptable and unnecessary alteration in technical contexts where the actual values matter.
% normalize to data extents
B = mat2gray(A);
[min(B(:)) max(B(:))] % but now it does span the full [0 1] range
ans = 1×2
0 1
If it's desired to have a floating-point image, one can simply rescale the data to suit the class
% normalize with respect to nominal class-specific range
C = A/65535;
% C = mat2gray(A,[0 65535]); % same thing
[min(C(:)) max(C(:))] % now the relative range is preserved
ans = 1×2
0.0275 0.9922
All of this could have been avoided by simply using im2double() instead of double. Unlike double(), im2double() casts and rescales the data like the prior example.
% avoid causing the problem in the first place
D = im2double(A0);
[min(D(:)) max(D(:))] % no need to fix anything
ans = 1×2
0.0275 0.9922