Creating an 8 bit uniform scalar quantizer

16 views (last 30 days)
KG573
KG573 on 22 Apr 2023
Edited: KG573 on 24 Apr 2023
I'm reading an image, "lena.raw" and converting it to 8x8 blocks with 4096 pixels. After converting it I then use a version of the Discrete Cosine Transform on each pixel individually. From there i set 50% of the coefficients starting from the higher frequency ones to zero.
On these blocks I'd like to create an 8 bit uniform scalar quantizer in order to compute the total number of bits to code the image and to compute the average number of bits per pixel. Is there a simple way to go about doing this? Or is something already prewritten inside of matlab for quantization?
clc;
clear all;
close all;
fid = fopen('lena.raw');
a = fread(fid,[512,512],'uchar');
fclose(fid);
a = a';
%% Converting to 8x8 Blocks %%
N1 = 8;
N2 = 8;
blocks = reshape(a,N1,N2,[]);
[N1,N2,pixels] = size(blocks);
%% Part 2 %%
%%%% DCT BLOCK %%%%
blocks_dct = zeros(N1,N2,pixels);
for pixel = 1:pixels
for k1 = 0:N1-1
for k2 = 0:N2-1
temp = 0;
for n1 = 0:N1-1
for n2 = 0:N2-1
%%% Do DCT %%%
temp = temp + (4*blocks(n1+1,n2+1,pixel)*cos(((pi*k1)/(2*N1))*((2*n1)+1))*cos(((pi*k2)/(2*N2))*((2*n2)+1)));
end
end
blocks_dct(k1+1,k2+1,pixel) = temp;
end
end
end
%%%% DCT BLOCK %%%%
blocks_dct_50 = blocks_dct;
%% Set 50% of Coefficients to Zero %%
for pixel = 1:pixels
counter = 0;
for k1 = 8:-1:1
for k2 = 8:-1:1
blocks_dct_50(k1,k2,pixel) = 0;
counter = counter + 1;
end
if counter == (N1*N2*.5)
break
end
end
end
%% Quantizer %%
[floor_min_50,loc_min] = min(blocks_dct_50(:));
[floor_max_50,loc_max] = max(blocks_dct_50(:));
thresh_50 = linspace(floor_min_50,floor_max_50,256);
value = linspace(0,256,257);
for pixel = 1:pixels
q_50(:,:,pixel) = imquantize(blocks_dct_50(:,:,pixel),thresh_50,value);
end

Answers (1)

Walter Roberson
Walter Roberson on 23 Apr 2023
quantize() or histogram (the 'bin' output) or rescale to 0 to 255*(1-eps) and floor()
  2 Comments
Walter Roberson
Walter Roberson on 24 Apr 2023
a = fread(fid,[512,512],'uchar');
fread defined uchar as 8 bit unsigned integer, same as uint8 .
Those are already 8 bit integer.
There are two possibilities for defining an "8 bit uniform scalar quantizer":
  1. You map the source uint8(0) to uint8(255) to 8 bit integers... getting out exactly the same value as the input; or
  2. You take the actual range of values present in any particular 8 x 8 block and define 256 uniform bins over that range, so bins will be at most 1 apart (if the data is 0 to 255) but may be closer than 1 apart (for example if a block happened to use the range 37 to 85 then the bins would be (85-37)/255 = 0.188 apart) -- in which case you would end up with empty intermediate bins
Neither version would seem to make much sense.
If your plan was to sort of convert each 8 x 8 block into a logically extended integer, 256^63*A(1,1) + 256^62*A(1,2) + 256^61*A(1,3) .... + 256^2*A(8,6) + 256*A(8,7) + A(8,8) and then quantize over that set of 4096 pseudo-integers, then a fair bit of the time the result would be the same as if you were to just take the first pixel of each block -- though not always.
KG573
KG573 on 24 Apr 2023
Hi Walter, thank you for the response, I've actually been working on the implementation for the code and this is what i've come up with:
%% Quantizer %%
[floor_min_50,loc_min] = min(blocks_dct_50(:));
[floor_max_50,loc_max] = max(blocks_dct_50(:));
thresh_50 = linspace(floor_min_50,floor_max_50,256);
value = linspace(0,256,257);
for pixel = 1:pixels
q_50(:,:,pixel) = imquantize(blocks_dct_50(:,:,pixel),thresh_50,value);
end
How exactly am I meant to calculate the total bits in the final image given that everythign is quantized from 0-256?
Would it be as simple as summing all the non-zero quantized values?
Also when it comes to calculating the average bits per pixel does that simply come down to a mean() after summing all the bits in an individual pixel?
My Initial Question was missing some information, I've edited the post.
EDIT:
I'm given an image to read in that is converted to a 512x512 double.
From the 512x512 double i'm supposed to convert that to 8x8 blocks with 4096 pixels.
After acquiring those blocks I'm supposed to perform the Discrete Cosine Transform on each pixel individually.
Then I set 50% of the coefficients to 0 starting with the higher frequency terms at the end of the matrix.
After that is when I begin using an 8 bit quantizer on the remaining coefficients on a per pixel basis.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!