Professional Documents
Culture Documents
Jpeg Compression Standards
Jpeg Compression Standards
Implemented in Matlab
By Michael Christensen
Abstract:
In this project I attempted to implement basic JPEG compression using only basic
Matlab functions. This included going from a basic grayscale bitmap image all the way
to a fully encoded file readable by standard image readers. I will show that I have
implemented the majority of the project, including much of the final binary coding.
Although I never obtained a fully completed image from my functions, I came very close.
Results:
In this section I will present the steps of obtaining a finalized JPEG file and how I
implemented each step in matlab. I will comment on possible improvements and
mistakes made in each case. The code used is attached at the end of this report.
Step1: Converting the base image to 8x8 matrices, DCT transform, quantizing
These steps were relatively easy, especially in matlab, which is specifically set up
to work with matrices. The 2-D discrete cosine transform is done simply with the dct2()
command. After splitting the matrix into 8x8 matrices and performing the DCT, a simple
piecewise division by the quantization matrix obtains the quantized matrices needed for
the next step.
Step 2: Zig-Zag Encoding of Quantized Matrices
I found no matlab implementation for this function, so I wrote one myself. I took
advantage of the fact that each diagonal row has addresses that add up to the same
number. Depending on whether the number is even or odd determined the direction of
the iteration through the row. The code I wrote is able to zig-zag through any matrix of
equal height and width. This could be useful if one wanted to experiment with deviding
images into matrices larger than 8x8.
Conclusion:
While not completing the goal I set out to achieve, I have demonstrated that
conversion from a grayscale image to the JPEG encoded binary bit stream is a fairly
simple and straightforward process. It comes as no surprise to me that the file I/O was
the most challenging part of the process.
As for where to go from here, I hope to complete the project in my free time and
publish the matlab files on the internet. I believe that while there are far more powerful
and efficient implementations of the JPEG algorithm out there, other students like myself
would benefit from a simple and straightforward implementation that emphasizes step-by
step explanations of what is going on and why.
function b = jpeg(file);
%
%
%
%
%
%
%
%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%
% Step 1: Read in the file, obtain parameters
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
A = imread(file); %reads file into a matrix
B = imfinfo(file); %reads file info
%convert to YCbCr
%if B.Format=='bmp'
%
A=rgb2ycbcr(A)
width=B.Width;
height=B.Height;
%detirmine number of 8x8 matrices, use ceil to round up
W=ceil(width/8);
H=ceil(height/8);
%create a matrix of zeros and add the image to it to fill out the 8x8
%matrices (matrix will stay the same size if height and width are
%divisible by 8
I=zeros(H*8,W*8,'uint8');
I(1:height,1:width)=A(1:height,1:width);
%divide numbers into WxH 8x8 matrices
X=zeros(H,W,8,8);
for J=1:H
for K=1:W
for j=1:8
for k=1:8
X(J,K,j,k)=I((J-1)*8+j,(K-1)*8+k);
end
end
end
end
%define
Q=[...
16
12
14
14
18
24
49
72
10
14
16
22
37
55
78
95
16
19
24
29
56
64
87
98
24
26
40
51
68
81
103
112
40
58
57
87
109
104
121
100
51
60
69
80
103
113
120
103
61
55
56
62
77
92
101
99];
b=[];
vprev=[];
vcurrent=[];
for J=1:H
for K=1:W
temp=zeros(8,8,'uint8');%create temporary matrix
temp(:,:)=X(J,K,:,:);%add values from current 8x8 sector
temp=double(temp);%convert numbers to double format(floating
point)
temp=temp-128;%shift mean to zero
temp=dct2(temp);%perform 2-D cosine transfer function
temp=temp./Q;%devide by quantization matrix
temp=round(temp);%round off the quantized matrix
vcurrent=zigzag(temp);%convert quantized matrix to 1-D vector
vcurrent=shorten(vcurrent);%remove extra zeros from vector
if J==1 && K==1
b=[b vecenc(vcurrent)];
else
vcurrent(1)=vcurrent(1) - vprev(1);%take difference of first
value
b=[b vecenc(vcurrent)];
end
vprev=vcurrent;
end
end
b=[head(Q) b 1 1 1 1 1 1 1 1
denote EOF End of File