How to reduce grayscale levels ?

I have an RGB image, converted it into Grayscale image X = imread('lena.bmp'); Y = rgb2gray(X); now the image is represented by 8 bits (256 levels) and i want to quantize this image "Y" by reducing the grayscale levels to 32 (5 bits), how to do that ?
i know i can show the image like this imshow(Y,colormap(gray(32))); but that will just show the image with 32 levels and i want to save it in a variable not just showing it off

 Accepted Answer

Use imquantize() or just divide the image by 8.
Y32 = Y / 8;

10 Comments

and what if i want 64 levels ?
For powers of 2 you can just divide by the number, so for 64 gray levels you would divide by 256/64 = 4. For 64 gray levels divide by 8, etc. If you want those gray levels spread over the entire range, then you need to multiply them by the number after dividing them. The division will truncate the fraction so you won't end up with the same values. Or if you have some non-power-of-2 number and want to specify the output levels, use imquantize() - it's much more general. If this answers the question, can you officially "Accept" it? Thanks in advance.
Honestly, it's not clear. you said * For powers of 2 you can just divide by the number, so for 64 gray levels you would divide by 256/64 = 4. For 64 gray levels divide by 8 * how come to divide by 4 for 64 levels, and at the same time divide by 8 also for 64 levels !! i need example please, i have a matrix (which is the grayscale image with 256 levels) and i want to quantize it by 32 levels (5 Bit "2^5")..is it as simple as dividing by 32 ? (Y32 = Y/32) ?? or what ?
Yes, it's that simple. Let's take a simple example of an 8 bit array being converted into numbers that are no more than 5 "1" bits.
Y = uint8([1, 3, 17, 42, 75, 166])
% Turn into numbers that can be represented in 5 bits.
% 5 bits means the max intensity would be 31
% Let's illustrate that by dividing by 256/2^5 = 8 = 2^3:
dec2hex(31) % Shows 1F which is 5 bits.
% Now do for our example.
Y8 = Y / 8 % shows 0 0 2 5 9 21
Of course Y8 is still a uint8 variable since there are no 2, 3, 4, 5, 6, or 7 bit variables, but the values can be expressed in no more than 3 bits.
just to make sure i got it, for 64 levels (6 bits) Y64 = Y / (256/2^6), for 32 levels (5 bits) Y32 = Y / (256/2^5), for 16 levels (4 bits) Y16 = Y / (256/2^4),...etc. is that correct ?
No. Look at the examples I gave. You divide by 2 to the 8 minus the number of bits you want, so y64 = y / (256/2^(8-6)).
To make it clear
256 2^8 8bit
128 2^7 7bit
64 2^6 6bit
32 2^5 5bit
16 2^4 4bit
8 2^3 3bit
4 2^2 2bit
2 2^1 1bit
Ok great, Thank you very much
For image Y, to convert from 256 levels to 32 levels, the values should be 0 to 31. But Y/8 may be 0 to 32. (e.g. 255/8 = 31.875 becomes 32). So, how can i solve this problem?
Use floor():
y8 = uint8(floor(double(y)/8))

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!