Creating an 8 bit uniform scalar quantizer
15 views (last 30 days)
Show older comments
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
0 Comments
Answers (1)
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
on 24 Apr 2023
a = fread(fid,[512,512],'uchar');
Those are already 8 bit integer.
There are two possibilities for defining an "8 bit uniform scalar quantizer":
- You map the source uint8(0) to uint8(255) to 8 bit integers... getting out exactly the same value as the input; or
- 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.
See Also
Categories
Find more on Quantizers in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!