2-DCT Image compression
이전 댓글 표시
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
Ibnsina Faiz Azzi
2022년 4월 22일
Is that compression by DCT ???
답변 (1개)
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
Prateek Suryawanshi
2021년 5월 26일
can you give full code pls.there are erroe while half above and half your code .
i want it today itself please.
nor saziana ariani sazali
2021년 6월 12일
@Pham Minh Hanh i try using this code but why i got different dimension from original? like original 236x236 after decompress i got 232x232..
nor saziana ariani sazali
2021년 6월 12일
ohh this code only valid for 512x512 dimension?
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
2021년 6월 25일
ohh i see..thankyou for explanation Walter
카테고리
도움말 센터 및 File Exchange에서 Image Transforms에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!