2-DCT Image compression

6 次查看(过去 30 天)
Amarnath R
Amarnath R 2018-11-3
Problem:
I tried implementing Discrete Cosine Transformation compression using matlab. Input image would a jpg image (Lena) having a size 512 X 512.
There are two stages namely compression and decompression.
Compression and Quantization:
The input image is converted to YCbCr component. Then Y component is taken up for compression. Further DCT will quantized.
Quantization and Decompression:
The quantized image is undergoes dequantization for decompression.
Issues:
Rectangular boxes are spotted in the decompressed version of the image. Is anything wrong with the code? For your inference, below are the sample input and output images and followed by the matlab code.
Input image:
Y Component in YCbCr:
Output image:
Code:
clc;
clear all;
close all;
I = imread('lena512.jpg');
figure, imshow(I);
% Y = I;
YCbCr = rgb2ycbcr(I);
figure, imshow(YCbCr);
Y = YCbCr(:,:, 1);
figure, imshow(Y);
[h, w] = size(Y);
r = h/8;
c = w/8;
s = 1;
q50 = [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];
% COMPRESSION
for i=1:r
e = 1;
for j=1:c
block = Y(s:s+7,e:e+7);
cent = double(block) - 128;
for m=1:8
for n=1:8
if m == 1
u = 1/sqrt(8);
else
u = sqrt(2/8);
end
if n == 1
v = 1/sqrt(8);
else
v = sqrt(2/8);
end
comp = 0;
for x=1:8
for y=1:8
comp = comp + cent(x, y)*(cos((((2*(x-1))+1)*(m-1)*pi)/16))*(cos((((2*(y-1))+1)*(n-1)*pi)/16));
end
end
F(m, n) = v*u*comp;
end
end
for x=1:8
for y=1:8
cq(x, y) = round(F(x, y)/q50(x, y));
end
end
Q(s:s+7,e:e+7) = cq;
e = e + 8;
end
s = s + 8;
end
% % % % % % % % % % % % % % %
% % DECOMPRESSION
% % % % % % %
s = 1;
for i=1:r
e = 1;
for j=1:c
cq = Q(s:s+7,e:e+7);
for x=1:8
for y=1:8
DQ(x, y) = q50(x, y)*cq(x, y);
end
end
for m=1:8
for n=1:8
if m == 1
u = 1/sqrt(8);
else
u = sqrt(2/8);
end
if n == 1
v = 1/sqrt(8);
else
v = sqrt(2/8);
end
comp = 0;
for x=1:8
for y=1:8
comp = comp + u*v*DQ(x, y)*(cos((((2*(x-1))+1)*(m-1)*pi)/16))*(cos((((2*(y-1))+1)*(n-1)*pi)/16));
end
end
bf(m, n) = round(comp)+128;
end
end
Org(s:s+7,e:e+7) = bf;
e = e + 8;
end
s = s + 8;
end
imwrite(Y, 'F:\workouts\phd\jpeg\input.jpg');
imwrite(uint8(Org), 'F:\workouts\phd\jpeg\output.jpg');
return;

回答(1 个)

Pham Minh Hanh
Pham Minh Hanh 2021-3-26
编辑:Pham Minh Hanh 2021-3-26
Your decompression code is not right. IDCT is defined by:
so that u and v have to be inside the 2nd loop, not outside. Here is my code. The right image is the input image, the left one is output. The decompressed image is similar to the input one, so DCT works well as expected.
for x = 1:8
for y = 1:8
comp = 0;
for m = 1:8
for n = 1:8
if m == 1
u = 1/sqrt(2);
else
u = 1;
end
if n == 1
v = 1/sqrt(2);
else
v = 1;
end
comp = comp + u*v*DQ(m, n)*(cos((((2*(x-1))+1)*(m-1)*pi)/16))*(cos((((2*(y-1))+1)*(n-1)*pi)/16));
end
end
bf(x, y) = round((1/4) *comp + 128);
end
  5 个评论
Walter Roberson
Walter Roberson 2021-6-12
That has nothing to do with the code shown by @Pham Minh Hanh and is because of the code provided by @Amarnath R
[h, w] = size(Y);
r = h/8;
c = w/8;
If Y is not an exact multiple of 8 rows or 8 columns, then r or c will not be integers. But when you use
for i=1:r
then the usual rules for the colon operator apply: the default step is 1 and you stop if the new value would exceed the upper bound, so the integers 1, 2, 3, 4, ... integer part of h/8 would be generated, and the for loop would not continue on to include the non-integer part of h/8 .
In order to use this code without discarding any pixels after the last full multiple of 8 pixels, then you need to pad Y with 0 as needed to make it an exact multiple of 8 rows or columns.
When you decode the image, make sure you pass through the original size so that you know how many padding pixels to discard.
nor saziana ariani sazali
ohh i see..thankyou for explanation Walter

请先登录,再进行评论。

产品


版本

R2014a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by