EE530 Image Processing Project #2
20215259 Kangmin Lee
2023.04.20
1. Scaler
1) For 1D sampling rate conversion for x2 conversion, the interpolation filters for sample-and-hold, linear
interpolation, and cubic convolution interpolation (a=-0.5) is found.
Impulse and Magnitude Response of Sample-and-hold Interpolation
Impulse and Magnitude Response of Linear Interpolation
Impulse and Magnitude Response of Cubic Interpolation
2) For 1D sampling rate conversion for x3 conversion, the interpolation filters for sample-and-hold, linear
interpolation, and cubic convolution interpolation (a=-0.5) is found.
Impulse and Magnitude Response of Sample-and-hold Interpolation
Impulse and Magnitude Response of Linear Interpolation
Impulse and Magnitude Response of Cubic Interpolation
3) The following procedures are repeated for barbara.png using the sample-and-hold, linear and cubic
interpolation.
barbara.png
(a) Scale the image by 3/2 by i) upsample the image by 3, ii) interpolate with a third band filter iii) anti-alias
with a half band filter, iv) and downsample by 2. Display the result.
barbara.png scaled by 3/2 (Sample-and-hold, Linear, Cubic)
(b) Scale the result by 2/3 by i) upsample the image by 2, ii) interpolate with a half band filter, iii) anti-alias with
a third band filter, iv) and downsample by 3. Display the result.
barbara.png scaled back by 2/3 (Sample-and-hold, Linear, Cubic)
4) The scaling performance of the sample-and-hold, linear and cubic interpolations is compared after x3/2 and
x2/3 conversions. The absolute error between the scaled and original images is shown. Also, the mean square
error (MSE) between the scaled and original images has been measured as follows.
Absolute Error between the Scaled and Original Images (Sample-and-hold, Linear, Cubic)
Note that the color black indicates 0 error.
MSE between the Scaled and Original Images (Sample-and-hold, Linear, Cubic)
We can find that the cubic interpolation has the least MSE, followed by linear interpolation, and then the
sample-and-hold interpolation.
5) A test image is prepared for the implementation of 2D filtering
Original Test Image
6) The filter is implemented with zero, repeated, and periodic boundary conditions. The filtered and difference
images are shown.
Filtered Images
Difference Images
2. Demosaicing
1) We are evaluating the performance of a demosaicing algorithm using RGB pixel data of the original image
kodim07.png .
kodim07.png (Original), kodim07r.png, kodim07g.png, kodim07b.png
2) The cubic interpolation filter is applied to find the missing RGB pixel data.
Demosaiced Image (Cubic)
3) The following interpolation filter is applied to find the missing RGB pixel data.
Interpolation Filter (Method3)
Demosaiced Image (Method3)
The mean square error (MSE) between the demosaiced and original images is measured as follows.
MSE between the Demosaiced and Original Images (Cubic, Method3)
3. JPEG
1) The image lena.tiff is compressed using the discrete cosine transform (DCT).
lena.tiff
2D DCT is applied for each [8 x 8] block of the original image to find the DCT coefficients. Then, the DCT
coefficient is quantized using the given quantization matrix. Finally, the inverse DCT is applied to the quantized
DCT coefficient to create the compressed image.
Compressed lena.tiff
The absolute error image and MSE is shown as below:
Absolute Error between the Compressed and Original Images
MSE between the Compressed and Original Images
Code
%% 1. Scaler
close all, clear all, clc
% 1) x2 conversion
a = -0.5;
impulse_sample2 = [0 0 0 0 1 1 0 0 0]; % sample-and-hold
magnitude_sample2 = abs(fft(impulse_sample2,512));
figure, stem(impulse_sample2)
figure, plot(magnitude_sample2)
xlim([0 500])
impulse_linear2 = [0 0 0 1/2 1 1/2 0 0 0]; % linear interpolation
magnitude_linear2 = abs(fft(impulse_linear2,512));
figure, stem(impulse_linear2)
figure, plot(magnitude_linear2)
xlim([0 500])
impulse_cubic2 = zeros(1,9); % cubic convolution interpolation
for i = -4:4
j = i/2;
if 0 <= abs(j) && abs(j) <= 1
impulse_cubic2(i+5) = (a+2)*abs(j)^3 - (a+3)*j^2 + 1;
elseif 1 <= abs(j) && abs(j) <= 2
impulse_cubic2(i+5) = a*abs(j)^3 - 5*a*j^2 + 8*a*abs(j) - 4*a;
end
end
magnitude_cubic2 = abs(fft(impulse_cubic2,512));
figure, stem(impulse_cubic2)
figure, plot(magnitude_cubic2)
xlim([0 500])
% 2) x3 conversion
impulse_sample3 = [0 0 0 0 0 0 0 1 1 1 0 0 0 0 0]; % sample-and-hold
magnitude_sample3 = abs(fft(impulse_sample3,512));
figure, stem(impulse_sample3)
figure, plot(magnitude_sample3)
xlim([0 500])
impulse_linear3 = [0 0 0 0 0 1/3 2/3 1 2/3 1/3 0 0 0 0 0]; % linear interpolation
magnitude_linear3 = abs(fft(impulse_linear3,512));
figure, stem(impulse_linear3)
figure, plot(magnitude_linear3)
xlim([0 500])
impulse_cubic3 = zeros(1,15); % cubic convolution interpolation
for i = -7:7
j = i/3;
if 0 <= abs(j) && abs(j) <= 1
impulse_cubic3(i+8) = (a+2)*abs(j)^3 - (a+3)*j^2 + 1;
elseif (1 <= abs(j)) && (abs(j) <= 2)
impulse_cubic3(i+8) = a*abs(j)^3 - 5*a*j^2 + 8*a*abs(j) - 4*a;
end
end
magnitude_cubic3 = abs(fft(impulse_cubic3,512));
figure, stem(impulse_cubic3)
figure, plot(magnitude_cubic3)
xlim([0 500])
% 3) Image interpolation
image1 = double(imread('barbara.png'));
figure, imshow(image1/255)
% scale the image by 3/2
image1_upsample3 = upsample(upsample(image1',3)',3); % upsample the image by 3
interpolate3 = impulse_sample3; % impulse_sample3, impulse_linear3, impulse_cubic3 % interpolate with
a third band filter
antialias2 = impulse_sample2; % impulse_sample2, impulse_linear2, impulse_cubic2 % anti-alias with a
half band filter
image1_interpolate3 = imfilter(image1_upsample3,interpolate3'*interpolate3);
image1_antialias2 = imfilter(image1_interpolate3,antialias2'*antialias2/sum(antialias2)^2);
image1_downsample2 = downsample(downsample(image1_antialias2',2)',2); % downsample the image by 2
figure, imshow(image1_downsample2/255)
% scale the image by 2/3
image1_upsample2 = upsample(upsample(image1_downsample2',2)',2); % upsample the image by 2
interpolate2 = impulse_sample2; % impulse_sample2, impulse_linear2, impulse_cubic2 % interpolate with
a half band filter
antialias3 = impulse_sample3; % impulse_sample3, impulse_linear3, impulse_cubic3 % antialias with a
third band filter
image1_interpolate2 = imfilter(image1_upsample2,interpolate2'*interpolate2);
image1_antialias3 = imfilter(image1_interpolate2,(antialias3'*antialias3)/(sum(antialias3)^2));
image1_scaled = downsample(downsample(image1_antialias3',3)',3); % downsample the image by 3
figure, imshow(image1_scaled/255)
% 4) MSE comparison
error = image1_scaled - image1;
error_squared = error.^2;
MSE = mean(error_squared(:))
figure, imshow(abs(error))
% 5) Test image
b = [ones(32,32),zeros(32,32);zeros(32,32),ones(32,32)];
b = [b,b;b,b];
figure; imshow(b);
% 6) Implement filter
% Define the filter
impulse_cubic = ones(5,5)/25;
b_zero = imfilter(b, impulse_cubic, 'replicate', 'same');
b_repeated = imfilter(b, impulse_cubic, 'symmetric', 'same');
b_periodic = imfilter(b, impulse_cubic, 'circular', 'same');
diff_zero = abs(b - b_zero);
diff_repeated = abs(b - b_repeated);
diff_periodic = abs(b - b_periodic);
figure,
subplot(3,4,1), imshow(b), title('Original Image');
subplot(3,4,2), imshow(b_zero), title('Zero Boundary');
subplot(3,4,3), imshow(b_repeated), title('Repeated Boundary');
subplot(3,4,4), imshow(b_periodic), title('Periodic Boundary');
subplot(3,4,5), imshow(diff_zero), title('Difference: Zero Boundary');
subplot(3,4,6), imshow(diff_repeated), title('Difference: Repeated Boundary');
subplot(3,4,7), imshow(diff_periodic), title('Difference: Periodic Boundary');
%% 2. Demosicing
close all, clear all, clc
% 1) Download the image
image2 = double(imread("kodim07.png"));
figure, imshow(image2/255);
image2_R = double(imread("kodim07r.png"));
figure, imshow(image2_R/255);
image2_G = double(imread("kodim07g.png"));
figure, imshow(image2_G/255);
image2_B = double(imread("kodim07b.png"));
figure, imshow(image2_B/255);
% 2) Cubic interpolation filter
a = -0.5;
impulse_cubic = zeros(1,9);
for i = -4:4
j = i/2;
if 0 <= abs(j) && abs(j) <= 1
impulse_cubic(i+5) = (a+2)*abs(j)^3 - (a+3)*j^2 + 1;
elseif 1 <= abs(j) && abs(j) <= 2
impulse_cubic(i+5) = a*abs(j)^3 - 5*a*j^2 + 8*a*abs(j) - 4*a;
end
end
image2_R_demosaic_cubic = imfilter(imfilter(image2_R,impulse_cubic),impulse_cubic');
image2_B_demosaic_cubic = imfilter(imfilter(image2_B,impulse_cubic),impulse_cubic');
image2_G_demosaic_cubic = (imfilter(image2_G,impulse_cubic)+imfilter(image2_G,impulse_cubic'))/2;
image2_demosaic_cubic =
cat(3,image2_R_demosaic_cubic,image2_G_demosaic_cubic,image2_B_demosaic_cubic);
figure, imshow(image2_demosaic_cubic/255);
% 3) Apply following interpolation filter
[m,n] = size(image2(:,:,1));
image2_G_demosaic_method3 = image2_G;
for i = 3:m-2
for j = 3:n-2
if mod(i,2) == 1 && mod(j,2) == 1 % G at R location
GR = (2*image2_G(i,j-1)+2*image2_G(i,j+1)+2*image2_G(i-
1,j)+2*image2_G(i+1,j)+4*image2_R(i,j) ...
-image2_R(i,j-2)-image2_R(i,j+2)-image2_R(i-2,j)-image2_R(i+2,j))/8;
image2_G_demosaic_method3(i,j) = image2_G_demosaic_method3(i,j) + GR;
elseif mod(i,2) == 0 && mod(j,2) == 0 % G at B location
GB = (2*image2_G(i,j-1)+2*image2_G(i,j+1)+2*image2_G(i-
1,j)+2*image2_G(i+1,j)+4*image2_B(i,j) ...
-image2_B(i,j-2)-image2_B(i,j+2)-image2_B(i-2,j)-image2_B(i+2,j))/8;
image2_G_demosaic_method3(i,j) = image2_G_demosaic_method3(i,j) + GB;
end
end
end
image2_R_demosaic_method3 = image2_R;
for i = 3:m-2
for j = 3:n-2
if mod(i,2) == 1 && mod(j,2) == 0 % R at G location in R row B column
RGRB = (4*image2_R(i,j-1)+4*image2_R(i,j+1)+5*image2_G(i,j)+(1/2)*image2_G(i-
2,j)+(1/2)*image2_G(i+2,j) ...
-image2_G(i-1,j-1)-image2_G(i-1,j+1)-image2_G(i+1,j-1)-image2_G(i+1,j+1)-image2_G(i,j-
2)-image2_G(i,j+2))/8;
image2_R_demosaic_method3(i,j) = image2_R_demosaic_method3(i,j) + RGRB;
elseif mod(i,2) == 0 && mod(j,2) == 1 % R at G location in B row R column
RGBR = (4*image2_R(i-1,j)+4*image2_R(i+1,j)+5*image2_G(i,j)+(1/2)*image2_G(i,j-
2)+(1/2)*image2_G(i,j+2) ...
-image2_G(i-1,j-1)-image2_G(i-1,j+1)-image2_G(i+1,j-1)-image2_G(i+1,j+1)-image2_G(i-
2,j)-image2_G(i+2,j))/8;
image2_R_demosaic_method3(i,j) = image2_R_demosaic_method3(i,j) + RGBR;
elseif mod(i,2) == 0 && mod(j,2) == 0 % R at B location in B row B column
RBBB = (2*image2_R(i-1,j-1)+2*image2_R(i-1,j+1)+2*image2_R(i+1,j-1)+2*image2_R(i+1,j+1) ...
+6*image2_B(i,j)-(3/2)*image2_B(i-2,j)-(3/2)*image2_B(i+2,j)-(3/2)*image2_B(i,j-2)-
(3/2)*image2_B(i,j+2))/8;
image2_R_demosaic_method3(i,j) = image2_R_demosaic_method3(i,j) + RBBB;
end
end
end
% Blue Patch
image2_B_demosaic_method3 = image2_B;
for i = 3:m-2
for j = 3:n-2
if mod(i,2) == 0 && mod(j,2) == 1 % B at G location in B row R column
BGBR = (4*image2_B(i,j-1)+4*image2_B(i,j+1)+5*image2_G(i,j)+(1/2)*image2_G(i-
2,j)+(1/2)*image2_G(i+2,j) ...
-image2_G(i-1,j-1)-image2_G(i-1,j+1)-image2_G(i+1,j-1)-image2_G(i+1,j+1)-image2_G(i,j-
2)-image2_G(i,j+2))/8;
image2_B_demosaic_method3(i,j) = image2_B_demosaic_method3(i,j) + BGBR;
elseif mod(i,2) == 1 && mod(j,2) == 0 % B at G location in R row B column
BGRB = (4*image2_B(i-1,j)+4*image2_B(i+1,j)+5*image2_G(i,j)+(1/2)*image2_G(i,j-
2)+(1/2)*image2_G(i,j+2) ...
-image2_G(i-1,j-1)-image2_G(i-1,j+1)-image2_G(i+1,j-1)-image2_G(i+1,j+1)-image2_G(i-
2,j)-image2_G(i+2,j))/8;
image2_B_demosaic_method3(i,j) = image2_B_demosaic_method3(i,j) + BGRB;
elseif mod(i,2) == 1 && mod(j,2) == 1 % B at R location in R row R column
BRRR = (2*image2_B(i-1,j-1)+2*image2_B(i-1,j+1)+2*image2_B(i+1,j-1)+2*image2_B(i+1,j+1) ...
+6*image2_R(i,j)-(3/2)*image2_R(i-2,j)-(3/2)*image2_R(i+2,j)-(3/2)*image2_R(i,j-2)-
(3/2)*image2_R(i,j+2))/8;
image2_B_demosaic_method3(i,j) = image2_B_demosaic_method3(i,j) + BRRR;
end
end
end
image2_demosaic_method3 =
cat(3,image2_R_demosaic_method3,image2_G_demosaic_method3,image2_B_demosaic_method3);
figure, imshow(image2_demosaic_method3/255)
% 4. MSE comparison
error_cubic = image2_demosaic_cubic - image2;
error_method3 = image2_demosaic_method3 - image2;
error_cubic_squared = error_cubic.^2;
error_method3_squared = error_method3.^2;
MSE_cubic = mean(error_cubic_squared(:))
MSE_method3 = mean(error_method3_squared(:))
%% JPEG
close all, clear all, clc
% 1) Apply 2D DCT
image3 = double(imread("lena.tiff"));
figure, imshow(image3/255);
% Define the quantization matrix Q
Q = [16, 11, 10, 16, 24, 40, 51, 61;
12, 12, 14, 19, 26, 58, 60, 55;
14, 13, 16, 24, 40, 57, 69, 56;
14, 17, 22, 29, 51, 87, 80, 62;
18, 22, 37, 56, 68, 109, 103, 73;
24, 35, 55, 64, 81, 104, 113, 92;
49, 64, 78, 87, 103, 121, 120, 101;
72, 92, 95, 98, 112, 100, 103, 99];
[height, width] = size(image3);
image3_compressed = zeros(height, width);
% Perform JPEG compression on 8x8 blocks
for i = 1:8:height
for j = 1:8:width
block = image3(i:i+7, j:j+7);
dct_block = dct2(block);
quantized_block = round(dct_block ./ Q);
reconstructed_block = idct2(quantized_block .* Q);
image3_compressed(i:i+7, j:j+7) = reconstructed_block;
end
end
figure, imshow(image3_compressed/255);
error = image3_compressed - image3;
error_squared = error.^2;
MSE = mean(error_squared(:))
figure, imshow(abs(error));