JPEG Image Compression Implemented in Matlab

**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.

Step 3: Conversion of quantized vectors into the JPEG defined bitstream

For this step, I started with an old implementation of the default AC code written by Yu Hen Hu. After updating the code to work with Matlab 7 I modified the code to encode the first number in the incoming vector with the default DC code, the table for which I added to the file. The function returns a completed bitstream to correspond to the input of the quantized vector.

I am sorry to say I cannot guarantee that the code contained in vecenc.m is at all reliable. I tested single vectors with standard examples and obtained the correct result. However, having never obtained a final result, I cannot guarantee that this function complies with the JPEG standard.

Step 4: Construction of the JPEG File header, Writing the File

Being relatively inexperienced with coding in general, this step presented me with the most trouble overall. It took several hours to determine how to encode a binary vector into a file. It took even longer to realize that each byte encoded into the file was being represented with the least significant bits on the left side. After overcoming that obstacle, I was faced with the task of constructing a file header for my bit stream.

The JPEG standard only goes as far as conversion to the binary bit stream. While that process is well defined in scientific papers, the construction of a JPEG file header is not. In the matlab file head.m, I tried to express what I learned about the process in the most expressive way possible.

It seems that the JPEG file is broken into many blocks. Each block begins with two bytes, the first being FF in hexadecimal and the second being ‘XX’ where different ‘XX’s denoting different blocks. The second part of each block is the length, in bytes, of the block including the two length bytes. The rest of the block contains the data as defined by the block type.

As of this writing, I am in the middle of coding head.m, but will be unable to finish due to time constraints. I am confident, though, that I have a very good understanding of how the rest of the header construction would proceed.

**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);

%

%

% Usage : Input an image file and recieve the jpeg implementation

% of the file.

%

% b: output binary stream

% file: input file

%

% by Michael Christensen December 14, 2005

%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%

% 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 luminance quantization matrix

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 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];

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 1 0 0 1 1 0 1 1];%last two bytes:ff d9 denote EOF End of File

## 3 comments:

Hi sir i need matlab code for JPEG Image Compression using wavelet.

suyogr@gmail.com

Pls mail me the code of IRIS Recognition using MATLAB

respected sir, can u pls mail me the codes for arithmatic coding technique! and find the compression ratios of 2 images!!

- rkvasudhara@gmail.com

## Post a Comment