convert 16 bit image to 8 bit image
167 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
how to convert 16 bit image to 8 bit image
0 comentarios
Respuesta aceptada
Jan
el 5 de Mzo. de 2012
The uint16 image used values from 0 to 2^16-1, while the uint8 images use a range from, 0 to 2^8-1 only. If you just cast the original values to uint8, the saturation will destroy a lot of information. Better use:
img8 = uint8(img16 / 256);
2 comentarios
dror yemini
el 10 de Sept. de 2020
yes but you loase somthing better before take bits with information so maybe do equalization of histogram before conversion ?
Más respuestas (3)
Rasmus Herlo
el 11 de Feb. de 2021
OBS: Jan's answer will do absolutely fine, if your image is optimized to use the entire scale. However, if your pixel values are only occupying a fraction of the available bits (common in much imaging), the direct conversion will lead to a significant loss of information. In addition, you might want to get your image on 1:2^16 (instead of 0:2^16-1) before normalizing.
Image conversion in software like ImageJ therefore uses linear scaling, and one would typically apply a similar approach here, by:
Input: Im16 'uint16' (any 16bit image)
dbIm16 = double(Im16)+1
dbIm16 = min(dbIm16(:)); db16max = max(dbIm16(:));
TgBit = 8; % or any other lower bit scale
% example with 16bit to 8bit
Norm_wOffSet = dbIm16/db16max; % maintaining putative offset from 0 in the data
Im8_wOffSet = uint8(Norm_wOffSet*2^TgBit-1); % back to 0:2^8-1
Norm_woOffSet = (dbIm16-db16min)/(db16max-db16min); % Scales linearly to full range
Im8_woOffSet = uint8(Norm_woOffSet*2^TgBit-1); % back to 0:2^8-1
1 comentario
Tiziana
el 21 de Nov. de 2022
Thank so much for your answer. Could I ask you the reasons of this "you might want to get your image on 1:2^16 (instead of 0:2^16-1) before normalizing"? Thank you very much.
Wayne King
el 5 de Mzo. de 2012
You can use uint8() to cast the image into unsigned 8-bit integers. Or int8() for signed 8-bit integers.
X = uint8(ones(10,10,'uint16'));
class(X)
0 comentarios
DGM
el 30 de Dic. de 2023
Editada: DGM
el 30 de Dic. de 2023
I don't know why nobody brought it up in 10+ years, but:
outpict = im2uint8(inpict); % recast with appropriate scaling
This will preserve the relative scale of the image regardless of the input class. Everything within the expected range of the input class (i.e. [-32768 32767] for int16) will fit within [0 255]. This works regardless of whether the input is int16 or uint16 or double, etc.
@Rasmus Herlo has a good point, though. A lot of technical and medical images in 16b seem to be unscaled raw values that occupy a small portion of the available dynamic range. Depending on the goals, it might be prudent to rescale them. That's easy enough.
outpict = im2uint8(mat2gray(inpict)); % normalize to extrema, then recast/scale
... though if the image is some sort of raw sensor data, a contextually-relevant nonlinear scaling might be more appropriate.
0 comentarios
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!