0% found this document useful (0 votes)
16 views7 pages

Computer Vision hw5

The document outlines a MATLAB implementation for JPEG compression and decompression, detailing the steps for image processing, including color space conversion, zero-padding, chroma subsampling, quantization, and block-based DCT. It includes functions for calculating quantization matrices based on quality factors and for computing RMSE against different quality factors. The final part demonstrates how to visualize the RMSE results for various quality factors applied to a sample image.

Uploaded by

zahraaalfaeq
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views7 pages

Computer Vision hw5

The document outlines a MATLAB implementation for JPEG compression and decompression, detailing the steps for image processing, including color space conversion, zero-padding, chroma subsampling, quantization, and block-based DCT. It includes functions for calculating quantization matrices based on quality factors and for computing RMSE against different quality factors. The final part demonstrates how to visualize the RMSE results for various quality factors applied to a sample image.

Uploaded by

zahraaalfaeq
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

Computer Vision

Homework 5:
JPEG Compression

Pesented by:

Zahraa muhaned mohammed faeq

MSc stg 1
1&2

jpeg _compression.m

function jpeg_compression(image_path, Q, downsamplingMode)

% 1. Read the image and convert it to YCbCr color space


img = imread(image_path);
img_ycbcr = rgb2ycbcr(img);
Y = img_ycbcr(:,:,1);
Cb = img_ycbcr(:,:,2);
Cr = img_ycbcr(:,:,3);

% 2. Zero-pad image components so their dimensions are divisible by 8 (or 16)


padToMultiple = @(channel, factor) padarray(channel, ...
mod(-size(channel), factor), 'post');

Y = padToMultiple(Y, [8, 8]);


Cb = padToMultiple(Cb, [8, 8]);
Cr = padToMultiple(Cr, [8, 8]);

% 3. Apply chroma subsampling depending on selected mode


switch downsamplingMode
case 'none'
% No downsampling
case 'h'
% Horizontal only
Cb = imresize(Cb, [size(Cb,1), floor(size(Cb,2)/2)], 'bilinear');
Cr = imresize(Cr, [size(Cr,1), floor(size(Cr,2)/2)], 'bilinear');
case 'h+v'
% Horizontal and vertical
Cb = imresize(Cb, floor(size(Cb)/2), 'bilinear');
Cr = imresize(Cr, floor(size(Cr)/2), 'bilinear');
otherwise
error('Invalid downsampling mode. Use "none", "h", or "h+v".');
end

% 4. Generate quantization matrices based on quality factor


[Qy, Qc] = getQuantMatrices(Q);

%% 5. Apply DCT + quantization block-by-block using blockproc


Y_q = blockproc(Y, [8 8], @(b) jpegBlockDCT(b, Qy));
Cb_q = blockproc(Cb, [8 8], @(b) jpegBlockDCT(b, Qc));
Cr_q = blockproc(Cr, [8 8], @(b) jpegBlockDCT(b, Qc));

figure;
subplot(1, 2, 1);
imshow(img);
title('Original Image');

% Reconstruct the image after compression (decoding part)


img_reconstructed = jpeg_decompression(Y, Y_q, Cb_q, Cr_q, Q, downsamplingMode);
subplot(1, 2, 2);
imshow(img_reconstructed);
title('Compressed Image');

% Optional: You can save or visualize the compressed result here


disp('JPEG compression completed successfully.');
end
% Function to compute quantization matrices based on quality factor
function [Qy, Qc] = getQuantMatrices(Q)
% Standard quantization matrices
Qy_std = [
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 77;
24 35 55 64 81 104 113 92;
49 64 78 87 103 121 120 101;
72 92 95 98 112 100 103 99];

Qc_std = [
17 18 24 47 99 99 99 99;
18 21 26 66 99 99 99 99;
24 26 56 99 99 99 99 99;
47 66 99 99 99 99 99 99;
99 99 99 99 99 99 99 99;
99 99 99 99 99 99 99 99;
99 99 99 99 99 99 99 99;
99 99 99 99 99 99 99 99];

% Compute scale factor


if Q < 50
S = 5000 / Q;
else
S = 200 - 2 * Q;
end

% Scale quantization matrices


Qy = round((S / 100) * Qy_std);
Qc = round((S / 100) * Qc_std);
end

% Function to apply range-shifting, DCT, and quantization to an 8x8 block


function outBlock = jpegBlockDCT(blockStruct, Qmat)
block = double(blockStruct.data) - 128; % Range shift to [-128, 127]
dct_block = dct2(block); % Apply 2D DCT
outBlock = round(dct_block ./ Qmat); % Quantize using Q matrix
end

function img_reconstructed = jpeg_decompression(Y, Y_q, Cb_q, Cr_q, Q, downsamplingMode)


% Reconstruct the quantization matrices
[Qy, Qc] = getQuantMatrices(Q);

% Apply inverse DCT and dequantization block-by-block


Y_dq = blockproc(Y_q, [8 8], @(b) jpegBlockInverseDCT(b, Qy));
Cb_dq = blockproc(Cb_q, [8 8], @(b) jpegBlockInverseDCT(b, Qc));
Cr_dq = blockproc(Cr_q, [8 8], @(b) jpegBlockInverseDCT(b, Qc));

% Resize the chroma channels to their original dimensions


switch downsamplingMode
case 'none'
% No resizing
case 'h'
Cb_dq = imresize(Cb_dq, [size(Cb_dq, 1), size(Cb_dq, 2) * 2], 'bilinear');
Cr_dq = imresize(Cr_dq, [size(Cr_dq, 1), size(Cr_dq, 2) * 2], 'bilinear');
case 'h+v'
Cb_dq = imresize(Cb_dq, [size(Cb_dq, 1) * 2, size(Cb_dq, 2) * 2], 'bilinear');
Cr_dq = imresize(Cr_dq, [size(Cr_dq, 1) * 2, size(Cr_dq, 2) * 2], 'bilinear');
otherwise
error('Invalid downsampling mode. Use "none", "h", or "h+v".');
end

% Reconstruct the full YCbCr image


img_ycbcr_reconstructed = cat(3, Y_dq, Cb_dq, Cr_dq);

% Convert YCbCr to RGB


img_reconstructed = ycbcr2rgb(img_ycbcr_reconstructed);

% Crop any padding added during compression


img_reconstructed = img_reconstructed(1:size(Y,1), 1:size(Y,2), :);
end

% Function to apply inverse DCT and dequantization to an 8x8 block


function outBlock = jpegBlockInverseDCT(blockStruct, Qmat)
block = double(blockStruct.data); % Get quantized block
block = block .* Qmat; % Dequantize using Q matrix
idct_block = idct2(block); % Apply inverse DCT
outBlock = uint8(idct_block + 128); % Range shift back to [0, 255]
end
In command window :

>> jpeg_compression('C:\Users\ahmed\Pictures\ph\2.jpg', 50, 'h+v');

JPEG compression completed successfully.

3. Choose an image, then apply the JPEG compression and decompression algorithms coded in steps 1
and 2 to plot the RMSE for each possible value of the quality factor Q.
function rmse_vs_q(image_path)
Q_values = 10:10:90;
RMSEs = zeros(size(Q_values));

original = im2double(imread(image_path));

for i = 1:length(Q_values)
Q = Q_values(i);
reconstructed = im2double(jpeg_compression(image_path, Q, 'h+v'));
RMSEs(i) = sqrt(mean((original(:) - reconstructed(:)).^2));
end

figure;
plot(Q_values, RMSEs, '-o');
xlabel('Quality Factor Q');
ylabel('RMSE');
title('RMSE vs JPEG Quality Factor');
grid on;
end

function img_reconstructed = jpeg_compression(image_path, Q, downsamplingMode)

img = imread(image_path);
img_ycbcr = rgb2ycbcr(img);
Y = img_ycbcr(:,:,1);
Cb = img_ycbcr(:,:,2);
Cr = img_ycbcr(:,:,3);

padToMultiple = @(channel, factor) padarray(channel, ...


mod(-size(channel), factor), 'post');

Y_padded = padToMultiple(Y, [8, 8]);


Cb_padded = padToMultiple(Cb, [8, 8]);
Cr_padded = padToMultiple(Cr, [8, 8]);

switch downsamplingMode
case 'none'
Cb_ds = Cb_padded;
Cr_ds = Cr_padded;
case 'h'
Cb_ds = imresize(Cb_padded, [size(Cb_padded,1),
floor(size(Cb_padded,2)/2)], 'bilinear');
Cr_ds = imresize(Cr_padded, [size(Cr_padded,1),
floor(size(Cr_padded,2)/2)], 'bilinear');
case 'h+v'
Cb_ds = imresize(Cb_padded, floor(size(Cb_padded)/2), 'bilinear');
Cr_ds = imresize(Cr_padded, floor(size(Cr_padded)/2), 'bilinear');
otherwise
error('Invalid downsampling mode. Use "none", "h", or "h+v".');
end

[Qy, Qc] = getQuantMatrices(Q);

Y_q = blockproc(Y_padded, [8 8], @(b) jpegBlockDCT(b, Qy));


Cb_q = blockproc(Cb_ds, [8 8], @(b) jpegBlockDCT(b, Qc));
Cr_q = blockproc(Cr_ds, [8 8], @(b) jpegBlockDCT(b, Qc));

img_reconstructed = jpeg_decompression(Y_padded, Y_q, Cb_q, Cr_q, Q,


downsamplingMode);
img_reconstructed = img_reconstructed(1:size(Y,1), 1:size(Y,2), :);% crop to
original
end
function [Qy, Qc] = getQuantMatrices(Q)
Qy_std = [
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 77;
24 35 55 64 81 104 113 92;
49 64 78 87 103 121 120 101;
72 92 95 98 112 100 103 99];

Qc_std = [
17 18 24 47 99 99 99 99;
18 21 26 66 99 99 99 99;
24 26 56 99 99 99 99 99;
47 66 99 99 99 99 99 99;
99 99 99 99 99 99 99 99;
99 99 99 99 99 99 99 99;
99 99 99 99 99 99 99 99;
99 99 99 99 99 99 99 99];

if Q < 50
S = 5000 / Q;
else
S = 200 - 2 * Q;
end

Qy = round((S / 100) * Qy_std);


Qc = round((S / 100) * Qc_std);
end

function outBlock = jpegBlockDCT(blockStruct, Qmat)


block = double(blockStruct.data) - 128;
dct_block = dct2(block);
outBlock = round(dct_block ./ Qmat);
end

function outBlock = jpegBlockInverseDCT(blockStruct, Qmat)


block = double(blockStruct.data);
block = block .* Qmat;
idct_block = idct2(block);
outBlock = uint8(idct_block + 128);
end

function img_reconstructed = jpeg_decompression(~, Y_q, Cb_q, Cr_q, Q,


downsamplingMode)
[Qy, Qc] = getQuantMatrices(Q);

Y_dq = blockproc(Y_q, [8 8], @(b) jpegBlockInverseDCT(b, Qy));


Cb_dq = blockproc(Cb_q, [8 8], @(b) jpegBlockInverseDCT(b, Qc));
Cr_dq = blockproc(Cr_q, [8 8], @(b) jpegBlockInverseDCT(b, Qc));

switch downsamplingMode
case 'none'
case 'h'
Cb_dq = imresize(Cb_dq, [size(Cb_dq, 1), size(Cb_dq, 2) * 2],
'bilinear');
Cr_dq = imresize(Cr_dq, [size(Cr_dq, 1), size(Cr_dq, 2) * 2],
'bilinear');
case 'h+v'
switch downsamplingMode
case 'none'
case 'h'
Cb_dq = imresize(Cb_dq, [size(Cb_dq, 1), size(Cb_dq, 2) * 2],
'bilinear');
Cr_dq = imresize(Cr_dq, [size(Cr_dq, 1), size(Cr_dq, 2) * 2],
'bilinear');
case 'h+v'
Cb_dq = imresize(Cb_dq, [size(Cb_dq, 1) * 2, size(Cb_dq, 2) * 2],
'bilinear');
Cr_dq = imresize(Cr_dq, [size(Cr_dq, 1) * 2, size(Cr_dq, 2) * 2],
'bilinear');
otherwise
error('Invalid downsampling mode.');

In command window

rmse_vs_q('C:\Users\ahmed\Pictures\ph\2.jpg')

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy