Creating an 8 bit uniform scalar quantizer
9 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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 comentarios
Respuestas (1)
Walter Roberson
el 23 de Abr. de 2023
quantize() or histogram (the 'bin' output) or rescale to 0 to 255*(1-eps) and floor()
2 comentarios
Walter Roberson
el 24 de Abr. de 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.
Ver también
Categorías
Más información sobre Quantizers en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!