Marorin Q
Marorin Q

Reputation: 27

Quantizing an image in matlab

So I'm trying to figure out why my code doesn't seem to be displaying the properly uniformed quantized image into 4 levels.

Q1 =uint8(zeros(ROWS, COLS, CHANNELS));
for band = 1 : CHANNELS,
    for x = 1 : ROWS,
        for y = 1 : COLS,

Q1(ROWS,COLS,CHANNELS) = uint8(double(I1(ROWS,COLS,CHANNELS) / 2^4)*2^4);
        end    
    end
end
No5 = figure;
imshow(Q1);
title('Part D: K = 4');

Upvotes: 1

Views: 2293

Answers (2)

Cris Luengo
Cris Luengo

Reputation: 60444

It is because you are not quantifying. You divide a double by 16, then multiply again by 16, then convert it to uint8. The right way to quantize is to divide by 16, throw away any decimals, then multiply by 16:

Q1 = uint8(floor(I1 / 16) * 16);

In the code snippet above, I assume I1 is a double. Convert it to double if its not: I1=double(I1).

Note that you don't need the loops, MATLAB will apply the operation to each element in the matrix.

Note also that if I1 is an integer type, you can do something like this:

Q1 = (uint8(I1) / 16) * 16;

but this is actually equivalent to replacing the floor by round in the first example. This means you get an uneven distribution of values: 0-7 are mapped to 0, 8-23 are mapped to 16, etc. and 248-255 are all mapped to 255 (not a multiple of 16!). That is, 8 numbers are mapped to 0, and 8 are mapped to 255, instead of mapping 16 numbers to each possible multiple of 16 as the floor code does.

The 16 in the code above means that there will be 256/16=16 different grey levels in the output. If you want a different number, say n, use 256/n instead of 16.

Upvotes: 1

docPhil
docPhil

Reputation: 190

It's because you are using ROWS, COLS, CHANNELS as your index, it should be x,y,band. Also, the final multiplication of 2^4 has be after the uint8 cast otherwise no rounding ever takes place.

In practice you should avoid the for loops in Matlab since matrix operations are much faster. Replace your code with

Q1=uint8(double(I1/2^4))*2^4
No5 = figure;
imshow(Q1);
title('Part D: K = 4');

Upvotes: 1

Related Questions