Creating an 8 bit uniform scalar quantizer
    16 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!
