change number of gray levels in a grayscale image in matlab

17,917

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:

enter image description here enter image description here enter image description here enter image description here

Now the same images but quantized by doing (img/(256/(2^bits)))*(256/(2^bits)):

enter image description here enter image description here enter image description here enter image description here

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.

Share:
17,917
krishnab
Author by

krishnab

Grad student at UCLA.

Updated on June 05, 2022

Comments

  • krishnab
    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
    s.bandara over 11 years
    Be careful with round. You will end up with 33 gray levels if I is not of integer type. If I is of integer type, you don't need any round. ;-)
  • Junuxx
    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
    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
    Junuxx over 11 years
    @mmgp: What do you recommend? Doing histogram equalization first?
  • mmgp
    mmgp over 11 years
    @Junuxx a method called improved grayscale quantization commonly provides better results, I might include an answer using it.