change number of gray levels in a grayscale image in matlab
Solution 1
While result = (img/8)*8
does convert a grayscale image in the range [0, 255] to a subset of that range but now using only 32 values, it might create undesirable artifacts. A method that possibly produces visually better images is called Improved Grayscale Quantization (abbreviated as IGS). The pseudo-code for performing it can be given as:
mult = 256 / (2^bits)
mask = 2^(8 - bits) - 1
prev_sum = 0
for x = 1 to width
for y = 1 to height
value = img[x, y]
if value >> bits != mask:
prev_sum = value + (prev_sum & mask)
else:
prev_sum = value
res[x, y] = (prev_sum >> (8 - bits)) * mult
As an example, consider the following figure and the respective quantizations with bits = 5
, bits = 4
, and bits = 3
using the method above:
Now the same images but quantized by doing (img/(256/(2^bits)))*(256/(2^bits))
:
This is not a pathological example.
Solution 2
You can reduce the number of different values in an image by simple rounding:
I = rgb2gray(imread('image.gif'));
J = 8*round(I/8)
See imhist(I)
and imhist(J)
for the effect.
However, if you want to reduce image size, you might be better off using an image processing program like Photoshop, Gimp or IrfanView and save as a 32 color gif. In that way you'll actually reduce the file's palette, and I think that's something Matlab can't do.
Comments
-
krishnab almost 2 years
I am rather new to matlab, but I was hoping someone could help with this question. So I have a color image that I want to convert to grayscale and then reduce the number of gray levels. So I read in the image and I used rgb2gray() to convert the image to grayscale. However, I am not sure how to convert the image to use only 32 gray levels instead of 255 gray levels.
I was trying to use colormap(gray(32)), but this seemed to have no effect on the plotted image itself or the colorbar under the image. So I was not sure where else to look. Any tips out there? Thanks.
-
s.bandara over 11 yearsBe careful with
round
. You will end up with 33 gray levels ifI
is not of integer type. IfI
is of integer type, you don't need anyround
. ;-) -
Junuxx over 11 years@s.bandara: Good point about rounding. Also it appears the OP might actually be looking for
imwrite
, using an appropriate map, but I don't have the time to figure it out now. -
mmgp over 11 years@Junuxx are you aware of how bad the resulting image will potentially look with this procedure ? (I commented this on your answer simply because it appeared at top when I visited this question, but this is equally valid for the other answers present here.)
-
Junuxx over 11 years@mmgp: What do you recommend? Doing histogram equalization first?
-
mmgp over 11 years@Junuxx a method called improved grayscale quantization commonly provides better results, I might include an answer using it.