-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTransform_coding.m
162 lines (156 loc) · 5 KB
/
Transform_coding.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
%% How to run: Just click "Run" button and hit "Select folder"
function Transform_coding()
close all;
clc;
imgdir = uigetdir('Test_images');
%% Loading directory, gray image
file = fopen(fullfile(imgdir,'\cameraman_gray_256x256.raw'),'rb');
gray_image = fread(file,fliplr([256,256]),'*uint8')';
fclose(file); gray_image = double(gray_image);
%% Starting
disp('Transform coding (8x8 block DCT + quantization)');
disp('Computing the 8x8 block DCT image...');
disp('Quantizing image...');
disp('Dequantizing image...');
disp('Inversing DCT 8x8 block image...');
% Computes output img
DCT8_img = DCT8(gray_image);
quantization_img = quantization(DCT8_img);
dequantization_img = dequantization(quantization_img);
IDCT8_img = IDCT8(dequantization_img);
% Computes psnr
psnr_inversed_img = psnr(uint8(IDCT8_img),uint8(gray_image));
disp(['PSNR: ', num2str(psnr_inversed_img), ' dB']);
% Displays figures
figure; imshow(gray_image,[]); title('Origional'); % show original image
figure; imshow(DCT8_img,[]); title('DCT block 8x8 image');
figure; imshow(quantization_img,[]); title('DCT block 8x8 quantization image');
figure; imshow(dequantization_img,[]); title('DCT block 8x8 dequantization image'); % show dequantization image
figure; imshow(IDCT8_img,[]); title('DCT block 8x8 inversed image'); % show inversed image
disp('Computing Completed!');
end
%% function to calculate DCT8x8
function y = DCT8(x)
[M,N] = size(x);
y = zeros(M,N);
for i=1:8:M
for j=1:8:N %jump to each block 8x8
block = myDCT2D(x(i:i+7,j:j+7));
y(i:i+7,j:j+7) = block; % give the output the value when apply DCT for each block
end
end
end
%% function quantization 8x8 block
function y = quantization(x)
% input must be 8x8 block DCT
[M,N] = size(x);
q_matrix = ... % the quantization parameter from 1 to 31
[ 31 22 23 21 24 5 22 4 ;
19 25 5 20 1 4 22 13 ;
26 10 30 20 23 26 2 11 ;
13 19 30 9 4 20 30 14 ;
31 2 29 14 22 22 8 11 ;
12 10 11 1 14 29 25 25 ;
2 21 24 13 3 25 21 7 ;
25 3 8 12 24 22 19 9 ];
% you can change an abitrary matrix for quantization
y = zeros(M,N);
for i=1:8:M
for j=1:8:N %jump to each block 8x8
block = x(i:i+7,j:j+7); % block 8x8
y(i:i+7,j:j+7) = round( block./(2*q_matrix)); % quantizing by dividing image block 8x8 to q_matrix and round them
end
end
end
%% function dequantization 8x8 block image
function y = dequantization(x)
% input must be 8x8 block DCT
[M,N] = size(x);
q_matrix = ...
[ 31 22 23 21 24 5 22 4 ;
19 25 5 20 1 4 22 13 ;
26 10 30 20 23 26 2 11 ;
13 19 30 9 4 20 30 14 ;
31 2 29 14 22 22 8 11 ;
12 10 11 1 14 29 25 25 ;
2 21 24 13 3 25 21 7 ;
25 3 8 12 24 22 19 9 ];
% this q-matrix must be same as the forward transform
y = zeros(M,N);
for i=1:8:M
for j=1:8:N %jump to each block 8x8
block = x(i:i+7,j:j+7); % block 8x8
y(i:i+7,j:j+7) = block.*(2*q_matrix); % dequantizing by multiplying image block 8x8 to q_matrix
end
end
end
%% function to calculate IDCT8x8
function y = IDCT8(x)
[M,N] = size(x);
y = zeros(M,N);
for i=1:8:M
for j=1:8:N %jump to each block 8x8
block = myIDCT2D(x(i:i+7,j:j+7));
y(i:i+7,j:j+7) = block; % give the output the value when apply IDCT for each block
end
end
end
%% function to calculate 2D DCT of an image
function y = myDCT2D(x)
signal = double(x);
N = size(signal,1);
y = zeros(N);
for k=1:N %calculate 1D DCT of each row of image
y(k,:) = myDCT1D(signal(k,:));
end
for k=1:N %calculate 1D DCT of each column of image
y(:,k) = myDCT1D(y(:,k));
end
end
%% function to calculate DCT of a 1D signal
function y = myDCT1D(signal)
N = length(signal);
signal = signal(:).';
alpha1 = sqrt(2/N);
for i=1:N
if i==1 %for signal index of 1, alpha is 1/sqrt(l)
alpha = sqrt(1/N);
else
alpha = alpha1;
%for signal index of greater than 1
end
j=1:N;
% summation calculates single entry of output by applying the
summ = sum(signal.*cos((pi*(2*(j-1)+1).*(i-1))/(2*N))); % formula of DCT on the signal
y(i) = alpha*summ;
end
end
%% function to calculate 2D IDCT of an image
function y = myIDCT2D(x)
y = IDCT_matrix(IDCT_matrix(x).').';
end
%function to calculate the IDCT column of a matrix
function y = IDCT_matrix(x)
y = zeros(size(x,1),1);
for i = 1:size(x,2)
y = [y myIDCT1D(x(:,i)')];
end
y = y(:,2:end);
end
%% function to calculate IDCT of a 1D signal
function y = myIDCT1D(x)
N = length(x);
CN = zeros(N);
alpha = sqrt(2/N);
alpha1 = sqrt(1/N);
for n=0:N-1
for k=0:N-1
if k==0
CN(k+1,n+1)=alpha1;
else
CN(k+1,n+1)=alpha*cos(pi*(n+0.5)*k/N); %using the formula of IDCT
end
end
end
y = CN'*x'; %sum all result to get the output
end