Anda di halaman 1dari 54

ENGI-4557

Digital
Communications
Jonathan
Evangelista Brian
England
Lucas Muller

[JPEG IMAGE
COMPRESSION]
The paper analyzes JPEG image compression utilizing the discrete cosine
transform algorithm, quantization tables for compression quality factors and runlength encoding technique.

ENGI-4557

Digital Communications 1
JPEG Image Compression

Table of Contents
Introduction................................................................................................................ 2
Discrete Cosine Transform.......................................................................................... 3
DCT in Basis Vectors................................................................................................ 5
MATLAB Functions for Discrete Cosine Transform dct2 and idct2..........................8
Zig Zag Transformation.............................................................................................. 9
Run-Length Encoding................................................................................................ 10
Message Decoding................................................................................................ 12
Quantization for a JPEG Image.................................................................................. 12
Appendix A Code for DCT and Graphical User Interfaces (GUIs)...........................16
DCT as Basis Vectors (DCTTest.m).........................................................................16
JPEG Compression (used only for a sample block) (JPEGCompression.m)............17
JPEG Compression for Gray Scale Image (used in Lena Image)
(JPEGCompressionGrayscale,m)............................................................................ 19
90% Compression (JPEGCompression90.m)..........................................................21
10% Compression (JPEGCompression10.m)..........................................................23
Homepage (Homepage.m).................................................................................... 25
DCT Test Using Basis Vectors (DCTTest.m)............................................................27
GUI For Test Bench First Page (DCTFig.m)..............................................................28
GUI For Test Bench Second Page (DCTFig2.m).......................................................33
GUI for Lena First Page (DCTLena.m).....................................................................36
GUI For Lena Second Page (DCTLena2.m).............................................................38
Zig Zag Transform for Quantized, Rounded Matrix (zigzag.m)............................44
Run Length Encoding for Zig Zag Transformed Image (RLE_encode.m)..............46
Run Length Decoding for Received Encoded Image (RLE_decode.m)....................47
Inverse Zig Zag Function for Decoded Image (invzigzag.m)...............................48
Appendix B MATLAB Graphical User Interfaces......................................................50
Works Cited................................................................................................................. 52

ENGI-4557

Digital Communications 2
JPEG Image Compression

ENGI-4557

Digital Communications 3
JPEG Image Compression

Introduction
This project analyzes the method of modifying a raw image in spatial domain, such as a bitmap
file, into a compressed state. The compression method used is JPEG compression. The discrete
cosine transform (DCT) formula is a mathematical algorithm which takes the values of an image
in spatial domain and transforms them to the frequency domain; which is required for the
compression. A quantization table determines the type and amount of compression which is
desired on the image which is to be reconstructed. Many redundant high frequency values from
the image are removed using run-length encoding. This is what ultimately reduces the size of the
image file. Once the image is to be viewed, the file is decoded and reconstructed. The final
result is a compressed image.

ENGI-4557

Digital Communications 4
JPEG Image Compression

Discrete Cosine Transform


The Discrete Cosine Transform (DCT) is a relative of the Discrete Fourier Transform (DFT).
The key difference between the two is that DCT uses only real numbers, hence cosine.
The forward DCT takes a signal from the spatial domain and transforms it into the frequency
domain. This provides many values of zero in the transformed matrix which will allow for
efficient encoding such as run-length or Huffman (run-length used in this project). The inverse
DCT (IDCT) does the exact opposite, where the signal from the frequency domain is transformed
back into the spatial domain to provide a reconstructed image.
In image compression, DCT is two-dimensional, as opposed to single-dimensional DCT which
would be used in sound wave compression, for example.
In JPEG compression, an original image of raw data (such as a bitmap file) is divided into blocks
of 8x8 pixel values, which represent a colour with an unsigned integer from 0-255. Once the
blocks are segmented, DCT is applied to them to obtain coefficients in the frequency domain.
The 8x8 block size was determined by the DCT algorithm which was able to be implemented in
VLSI (very large scale integration).
The formula which describes the forward discrete cosine transform is:
7

( 2 x +1 ) u
( 2 y +1 ) v
1
F ( u , v )= C u C v f ( x , y ) cos
cos
4
16
16
x=0 y=0

) (

(Eq. 1.1)

The formula which describes the inverse discrete cosine transform is:
7

( 2 x +1 ) u
( 2 y+ 1 ) v
1
F ( x , y )= C u C v f (u , v ) cos
cos
4
16
16
u=0 v=0
In both above cases,
Cu =

1
1
,u=0
, v=0
,
C
=
v
2
2
1,u 0
1,v 0

) (

(Eq. 1.2)

Digital Communications 5
JPEG Image Compression

ENGI-4557

The best way to understand this formula is to analyze a simple mathematical example. Observe
the 8x8 block of pixels below:
v
*

*
u

Figure 1.1

In the above 8x8 table which represents an 8x8 block of pixels, each asterisk (*) represents a
pixel with a value from 0-255. To get an idea of how the DCT formula works, an X has been
placed in the table in the 4th column and 3rd row, and this specific pixel will be analyzed in the
formula:
7

( 2 x +1 ) u
( 2 y +1 ) v
1
F ( u , v )= C u C v f ( x , y ) cos
cos
4
16
16
x=0 y=0

) (

So in this case, u = 3, and v = 2 because the eight columns and rows are from values 0 to 7 (not 1
to 8). Since u and v are not equal to zero, both Cu and Cv are both equal to 1. This yields the
equation below:
7
7
( 2 x+ 1 ) 3
( 2 y +1 ) 2
1
F ( 3,2 )= f ( x , y ) cos
cos
4 x=0 y=0
16
16

) (

(Eq. 1.3)

ENGI-4557

Digital Communications 6
JPEG Image Compression

Solving the DCT formula would provide the DCT coefficient which is desired at this location of
the 8x8 block.
The position of DCT coefficients in the new 8x8 block of values in the frequency domain can be
represented as a high frequency or low frequency value. Below is an image provided by XIL
Programmers Guide August 1994 and gives an illustration to explain the frequency
distribution or DCT coefficient distribution in any given 8x8 block

Figure 1.2
The inverse DCT would provide the coefficient which is desired in the original state of the raw
image in the spatial domain.

DCT in Basis Vectors


An alternate way of viewing the DCT formula is in terms of basis vectors. Below is the formula
for this method:
7

F ( u , v )= p ( y , x ) d u [ x ] d v [ y ]
x=0 y=0

(Eq. 1.4)

ENGI-4557

Digital Communications 7
JPEG Image Compression

Where:

f 00 f 07
F=
f 70 f 77

] [
,

p 00
P=
p 70

p07

p77

] [
,

d 00 d 07
D=
d 70 d 77

And f vu=F ( v ,u ) , p yx =p ( y , x ) , d t =d [t]


The P matrix is the raw image matrix of spatial domain values.

The D matrix is represented by:


d [ t ]=

C ()
(2t +1)
cos
2
16

(Eq. 1.5)

Where,
C()=

1
, =0
,
2
1, 0

And,
=uv
t={0,1,2, , 7 }
Observing these matrices, a comparison can be made to the original DCT equation (Eq. 1.1).
MATLAB code may be useful in understanding the methodology of the DCT in basis vectors.
The example below will go through the process of obtaining DCT coefficients from a raw image
8x8 block of values in the spatial domain:
%This is an example of an 8x8 block of spatial domain values. Each value
%represents an unsigned integer from 0 - 255 to represent a colour.
P0 =

[139 144 149 153 155 155 155 155;


144 151 153 156 159 156 156 156;

ENGI-4557
150
159
159
161
162
162

155
161
160
161
162
162

160
162
161
161
161
161

163
160
162
161
163
161

158
160
162
160
162
163

156
159
155
157
157
158

156
159
155
157
157
158

Digital Communications 8
JPEG Image Compression

156;
159;
155;
157;
157;
158];

%The line below subtracts 128 from each element in the above matrix to
%make an signed integer to work with for the DCT algorithm.
P = P0 - 128;
%The two lines below are to produce the C(omega) term in Eq. 1.5.
S = eye(8)/2;
S(1,1) = 1/2/sqrt(2);
%Below, the DCT vectors are arranged and then multiplied by S to complete
%equation Eq 1.5.

D = zeros(8,8);
for t = [0:7]
for w = [0:7] %where w is u and v
D(w+1, t+1) = cos((2*t+1)*w*pi/16);
end
end
%Equation Eq. 1.5 therefore is:
D = S * D;
%Perform forward DCT to obtain the 8x8 matrix of DCT coefficients.
F = D * P * D';

This program outputs the 8x8 matrix value of F (which would further be rounded to 0 decimal
places):

ENGI-4557

Digital Communications 9
JPEG Image Compression

This is one possible way to achieve DCT coefficients in MATLAB, and is simply just an
explanation of the formula. In the case of this project, the MATLAB functions dct2 and
idct2 are utilized.

MATLAB Functions for Discrete Cosine Transform dct2 and


idct2
The algorithm used in this project is generated through MATLAB. From the help
option, the following information is found which explains the dct2 algorithm in minor detail:

ENGI-4557

Digital Communications 10
JPEG Image Compression

Zig Zag Transformation


After the 8x8 matrix of values has been quantized by the source device, the information
must be sent as a string of bits to the receiver. In order to do this, we first use the Zig Zag
Transform to change the two-dimensional matrix into a one-dimensional array of entries.
Starting from the top-left corner, the transform scans in an alternating up-right and downleft pattern, gathering the values from the matrix and inserting them one at a time into the onedimensional output array. The code first checks if the scanning is moving in the up-right or
bottom-left direction by checking the modulo 2 sum of the current X and Y coordinate, that is to
say that if the sum of the X and Y coordinates divided by two has a remainder of zero, then the
scan is moving in the up-right direction and otherwise, it is moving in the down-left direction.
This process is shown in Figure 2.1. Note that this process of checking the modulo 2 sum, all
entries on a diagonal have the same sum and therefore have the same base rules as the rest of the
nodes in that diagonal.

Figure 2.1
Once the basic direction of the node has been determined, additional rules are required
for the proper functionality of the Zig Zag transformation.
For the case where the modulo 2 sum equals zero, the diagonals have even numbered
coordinate sums. When the X coordinate is at the minimum (1) and Y is at the maximum (8), the
current node is the top-right and it must move down-left one space. If the X coordinate is at the
minimum elsewhere, the code must move one space to the right. If the Y coordinate is at the

ENGI-4557

Digital Communications 11
JPEG Image Compression

maximum and the X coordinate is anywhere but the minimum, the code moves down one space.
Any other spaces with even coordinate sums result in the code reading the value and move upright.
For cases where the modulo 2 sum is not zero, the diagonals have odd numbered
coordinate sums. When the X coordinate is at the maximum and the Y coordinate is not at the
maximum, the entry is at the lower left corner and the code moves one space to the right. If the Y
coordinate is at the minimum and the X coordinate is at any value less than the maximum, the
code moves down one space. Any other spaces with odd coordinate sums result in the code
reading the value and move down-left.
Lastly, then the code reads the value with X and Y at the maximum and copies that entry
into the output array, the Zig Zag transformation is complete. At this point, the output array
should contain most of the non-zero values at the beginning of the array followed by the zero
values in large sequential group, or several smaller sequential groups divided by non-zero values.
It is at this point that the output array will be Run-Length Encoded to reduce the number of bytes
and subsequently increase the transmission speed.

Run-Length Encoding
The Run-Length Encoding receives a one-dimensional array of any size and scans
through each entry. It first reads the entry and adds that value to the one-dimensional output
array. Next, it checks ahead in the input array until the value is not equal to the first one scanned.
The number of entries checked is then added as the next value in the output array. As shown in
figure 2.2, the code reads a value of 8 which is repeated 3 times in a row; value 0 which only
occurs once in a row; value 4 which is repeated twice; and value 0 again, which is repeated twice
this time.
Input Array

Output Array

[8, 8, 8, 0, 4, 4, 0, 0]

[8, 3, 0, 1, 4, 2, 0, 2]

Figure 2.2
In this particular case, Run-Length Encoding has not saved any space these values can
be assumed to use 4 bits per entry and both the input and output arrays have 8 entries each, 32
bits total. However, this method is incredibly useful with JPEG compression since the quantized
rounded matrix contains a short list of non-zero values in the upper right corner and is heavily
populated by zeros elsewhere. After the Zig Zag Transformation, this results in an array
containing 64 entries, mostly sequential zeros. This case can be seen in figure 2.3.

ENGI-4557

Digital Communications 12
JPEG Image Compression

Input Array

Output Array

[1, 2, 3, 4, 0, 0, 0, 0, , 0]

[1, 1, 2, 1, 3, 1, 4, 1, 0, n]

Figure 2.3
The Run-Length Encoding clearly loses efficiency when encoding values that are not
repeated since the output contains the value and the number of sequential entries (in this case, 1),
effectively doubling the number of bits required. However, each time a value is sequentially
repeated, we have saved bits equal to one entry. When we apply this to the Zig Zag transformed
quantized rounded matrix, we receive an output array that is significantly shorter than the 64entry matrix that we started with.
At this point, it would be possible to use Huffman encoding to further reduce the size of
the transmitted message but for the scope of this project, this step is complex and unnecessary.
The image has been compressed and can now be transmitted to another device.
See Figure 2.4 below for the complete process:

Message Decoding
Following the transmission of the message from the source device to the receiver, the
message must be converted back into a readable format in order for the receiver to perform
transform operations to covert the data into the compressed JPEG image.

ENGI-4557

Digital Communications 13
JPEG Image Compression

Firstly, the encoded array must be inflated back into a one-dimensional array containing
64 entries. To do this, the Run-Length Encoding must be reversed by reading the first entry in the
input array, adding that value to the output array N times, where N is the number following the
value. This process is repeated until the input array has been completely read, which should be a
total of 64 entries.
Following the reverse Run-Length Encoding, the receiver must perform reverse Zig Zag
encoding to return values to their correct locations. This is done in a very similar way to the
regular Zig Zag encoding process. An 8x8 output matrix is initialized with all zeros and the
decoder moves through it in the exact same way as the encoder did before transmitting the
message. The only difference is that in this case, the values from the reverse Run-Length
Encoded message are read and entered into the current entry of the output matrix. The result of
this process is identical to the Quantized Rounded Matrix that the source device had created
before the transmission and encoding steps.
From this point, the receiving device may continue to use inverse transform methods to
recreate the viewable compressed JPEG image.

Quantization for a JPEG Image


Quantization involved in image compression is a lossy compression technique which is
achieved by compressing a range of values to a single quantum value. By reducing the number of
symbols in a given stream, the total stream of information becomes more compressible. In the
case of a jpeg image, reducing the number of colours to represent the digital image makes it
possible to reduce the file size. For JPEG images quantization is used in conjunction with
Discrete Cosine Transform to achieve the desired compression.
The human eye is very good at perceiving small differences in brightness over a large
area, but does not do so well when it comes to the exact strength of high frequency brightness
variation. This is what allows us to reduce the amount of information required to display the
image. The high frequency components are just ignored seeing as the eye cannot see the
differences anyways. This is accomplished by dividing the each component in the frequency
domain by a constant for that component and then rounding to the nearest integer. The result of
this procedure is that many of the high frequency components will be rounded down to zero and
many others will be small values either positive or negative.
The process of taking the DCT of an image is to establish the frequency values. Then
using the standard JPEG luminance and chrominance quantization matrices one can begin the
process of compressing the image. As describe above the DCT coefficient matrix is divided
element by element using one of the quantization matrix and then rounding to the nearest integer

ENGI-4557

Digital Communications 14
JPEG Image Compression

which will gives us the quantized coefficients of the DCT values. An example is shown below of
this process using the standard luminance quantization matrix:
.

Figure 3.1 - DCT Coefficient Matrix

Fig 3.2 - Standard Luminance Quantization Matrix


Once we have the DCT coefficient matrix, we begin by dividing each element by
corresponding element in the standard luminance quantization matrix and then rounding to the
nearest integer to get the table shown below.

Digital Communications 15
JPEG Image Compression

ENGI-4557

Fig 3.3 - Normalized Quantized Coefficient Table


It can be seen from the normalized quantized coefficient table that there many zeroes.
These were the high frequency components of the image that have been reduced to zero or small
values. The low frequency components of the image are all grouped in the upper left corner of
the table. From here we can begin the process of encoding.
If another level of compression is desired, the standard JPEG luminance and chrominance
quantization matrices can be used as a base to adjust the quality factor of the image. This is
accomplished by setting the desired quality factor; and depending on the set value, it will fall
under one of two conditions:

qf <50 qf >50
Scale=5000/qf Scale=2002 qf

The standard JPEG luminance and chrominance quantization matrices are already set to a
quality factor of 50, this is why two conditions exists. By determining which quality factor is
used, the standard tables can scaled up or down. The equation below shows the formula to
calculate the new table values based on the desired quality factor used.
Qnew=

Q50Scale+50
100

The higher the quality factor used, the more the image will retain its integrity, i.e., less
compression will occur.

ENGI-4557

Digital Communications 16
JPEG Image Compression

The two quantization tables shown above have a quality factor of 10 and 90. What is
noticed is that a quality factor (qf) of 10 will cause the most compression to occur because it will
eliminate a large portion of the high frequency components. With a qf=90, the image will end up
retaining a large portion of the original values so less compression is achieved.
With the quality factor determined, the process of finding the normalized quantized
coefficient table is the same as described previously. Once this table has been calculated,
encoding can begin.

ENGI-4557

Digital Communications 17
JPEG Image Compression

Appendix A Code for DCT and Graphical User Interfaces


(GUIs)
DCT as Basis Vectors (DCTTest.m)
%This is an example of an 8x8 block of spatial domain values. Each value
%represents an unsigned integer from 0 - 255 to represent a colour.
P0 =

[139
144
150
159
159
161
162
162

144
151
155
161
160
161
162
162

149
153
160
162
161
161
161
161

153
156
163
160
162
161
163
161

155
159
158
160
162
160
162
163

155
156
156
159
155
157
157
158

155
156
156
159
155
157
157
158

155;
156;
156;
159;
155;
157;
157;
158];

%The line below subtracts 128 from each element in the above matrix to
%make an signed integer to work with for the DCT algorithm.
P = P0 - 128;
%The two lines below are to produce the C(omega) term in Eq. 1.5.
S = eye(8)/2;
S(1,1) = 1/2/sqrt(2);
%Below, the DCT vectors are arranged and then multiplied by S to complete
%equation Eq 1.5.
D = zeros(8,8);
for t = [0:7]
for w = [0:7] %where w is u and v
D(w+1, t+1) = cos((2*t+1)*w*pi/16);
end
end
%Equation Eq. 1.5 therefore is:
D = S * D;
%Perform forward DCT to obtain the 8x8 matrix of DCT coefficients.
F = D * P * D';

ENGI-4557

Digital Communications 18
JPEG Image Compression

JPEG Compression (used only for a sample block)


(JPEGCompression.m)
%JPEG Compression using 50% quantization table
P0original =

[139
144
150
159
159
161
162
162

144
151
155
161
160
161
162
162

149
153
160
162
161
161
161
161

153
156
163
160
162
161
163
161

155
159
158
160
162
160
162
163

155
156
156
159
155
157
157
158

155
156
156
159
155
157
157
158

155;
156;
156;
159;
155;
157;
157;
158]; %Original 8x8 Matrix.

P0 = P0original - 128; %Subtracts 128 from original 8x8 Matrix (for a signed
integer rather than unsigned).
P0fDCT = roundn(dct2(P0), 0); %Calculates forward DCT of P0.
Q0 =

[16
11
10
16
24
40
12
12
14
19
26
58
14
13
16
24
40
57
14
17
22
29
51
87
18
22
37
56
68
109
24
35
55
64
81
104
49
64
78
87
103
121
72
92
95
98
112
100
quantization matrix (for 50% compression)

51
60
69
80
103
113
120
103

61;
55;
56;
62;
77;
92;
101;
99]; %This is the

%The script below will determined the normalized quantized coefficients by


%dividing, element by element, P0fDCT/Q0.
Q0Norm = ldivide(Q0, P0fDCT); %Produces the normalized quantized coefficient
matrix.
Q0NormRounded = roundn(Q0Norm, 0); %Rounds the normalized quantized
coefficient matrix.
%-------------------------------------------------------------------------%
%Now the quantized matrix is formed, perform zig zag scan run-length
%encode.
%Once the file is encoded (i.e., after run-length encoding), run the rest
%of the script to decode the file and reconstruct the image.
%-------------------------------------------------------------------------%
Q0DeNorm = times(Q0NormRounded,Q0); %Produces the denormalized quantized
coefficient matrix.

ENGI-4557

Digital Communications 19
JPEG Image Compression

%Now that the denormalized quantized matrix is obtained, the image needs to
%be reconstructed to its compressed 8x8 matrix.
Q0Reconstructed = idct2(Q0DeNorm); %Inverse Discrete Cosine Transform to
reconstruct image.
Q0Reconstructed128 = Q0Reconstructed + 128; %Adds 128 to the signed integer to
make it once again an unsigned 0-255 integer.
Q0ReconstructedRounded = roundn (Q0Reconstructed128, 0); %Rounds the matrix
values to integers.
%Now compressed image is reconstructed

ENGI-4557

Digital Communications 20
JPEG Image Compression

JPEG Compression for Gray Scale Image (used in Lena Image)


(JPEGCompressionGrayscale,m)
%This breaks a 2 dimensional grayscale image, "lena512.bmp" into 8x8 blocks
%and performs a compression.
n = 1; %set "n" variable to 1
m = 1; %set "m" variable to 1
I = imread('lena512.bmp'); %read in the image
%The ridiculously inefficient line below breaks up the 512x512 grayscale
%image into 8x8 blocks of pixels
P0original = mat2cell(I,[8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8], [8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8]);
while (n <= 64) && (m <= 64) %while loop to analyze each individual 8x8 block
in the image and perform compression based on specified quantization
%matrix, "Q0"
P0{m,n} = P0original{m,n} - 128; %subtracts 128 from each original value
to make it a signed integer (as opposed to unsigned)
P0fDCT{m,n} = roundn(dct2(P0{m,n}), 0); %performs two dimensional
discrete cosine transform to bring values from spatial
%domain into the frequency domain and rounds these values to zero
decimal places
Q0 =

[16
12
14
14
18
24
49
72

11
12
13
17
22
35
64
92

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

%Q0 above is the standard quantization table which uses 50% compression.
Q0Norm{m,n} = ldivide(Q0, P0fDCT{m,n}); %Normalization of the matrix
using element-by-element division (left-array-division)
Q0NormRounded{m,n} = roundn(Q0Norm{m,n}, 0); %Simply rounds the
normalized matrix
%At this point, the zig-zag algorithm would be run and process each 8x8
%block into a row vector so that the run-length algorithm can be applied to
%compress the image file for transmission
Q0DeNorm{m,n} = times(Q0NormRounded{m,n},Q0); %Denormalization of the
matrix via element-by-element multiplication

ENGI-4557

Digital Communications 21
JPEG Image Compression

Q0Reconstructed{m,n} = idct2(Q0DeNorm{m,n}); %Performs inverse


discrete cosine transform to bring values back to spatial domain
Q0Reconstructed128{m,n} = Q0Reconstructed{m,n} + 128; %Adds 128 to
each value convert values to unsigned integers
Q0ReconstructedRounded{m,n} = roundn(Q0Reconstructed128{m,n}, 0);
%Rounds each value to zero decimal places

n = n + 1; %Adds one to the n counter


if (n == 65) %'If statement' to allow each block in P0original{m,n} to
be scanned, i.e., from P0original{1,1} to P0original{64,64}
m = m + 1;
n = 1;
end %end of if statement
end %end of while loop
A = Q0ReconstructedRounded; %Reassign to a simpler variable
ICompressed = cell2mat(A); %Reassemble 8x8 blocks into a single 512x512 matrix
FinalImage = uint8(ICompressed); %Converts the file to an 8-bit unsigned
integer
%imshow(I);
%imshow(FinalImage);

ENGI-4557

Digital Communications 22
JPEG Image Compression

90% Compression (JPEGCompression90.m)


%This breaks a 2 dimensional grayscale image, "lena512.bmp" into 8x8 blocks
%and performs a compression.
n = 1; %set "n" variable to 1
m = 1; %set "m" variable to 1
I = imread('lena512.bmp'); %read in the image
%The ridiculously inefficient line below breaks up the 512x512 grayscale
%image into 8x8 blocks of pixels
P0original = mat2cell(I,[8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8], [8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8]);
while (n <= 64) && (m <= 64) %while loop to analyze each individual 8x8 block
in the image and perform compression based on specified quantization
%matrix, "Q0"
P0{m,n} = P0original{m,n} - 128; %subtracts 128 from each original value
to make it a signed integer (as opposed to unsigned)
P0fDCT{m,n} = roundn(dct2(P0{m,n}), 0); %performs two dimensional
discrete cosine transform to bring values from spatial
%domain into the frequency domain and rounds these values to zero
decimal places
Q10 = [80
55
70
70
90
120
245
255

60
60
65
85
110
175
255
255

50
70
80
110
185
255
255
255

80
95
120
145
255
255
255
255

120
130
200
255
255
255
255
255

200
255
255
255
255
255
255
255

255
255
255
255
255
255
255
255

255;
255;
255;
255;
255;
255;
255;
255];

Q0Norm{m,n} = ldivide(Q10, P0fDCT{m,n}); %Normalization of the matrix


using element-by-element division (left-array-division)
Q0NormRounded{m,n} = roundn(Q0Norm{m,n}, 0); %Simply rounds the
normalized matrix
%At this point, the zig-zag algorithm would be run and process each 8x8
%block into a row vector so that the run-length algorithm can be applied to
%compress the image file for transmission
Q0DeNorm{m,n} = times(Q0NormRounded{m,n},Q10); %Denormalization of the
matrix via element-by-element multiplication
Q0Reconstructed{m,n} = idct2(Q0DeNorm{m,n}); %Performs inverse
discrete cosine transform to bring values back to spatial domain

ENGI-4557

Digital Communications 23
JPEG Image Compression

Q0Reconstructed128{m,n} = Q0Reconstructed{m,n} + 128; %Adds 128 to


each value convert values to unsigned integers
Q0ReconstructedRounded{m,n} = roundn(Q0Reconstructed128{m,n}, 0);
%Rounds each value to zero decimal places

n = n + 1; %Adds one to the n counter


if (n == 65) %'If statement' to allow each block in P0original{m,n} to
be scanned, i.e., from P0original{1,1} to P0original{64,64}
m = m + 1;
n = 1;
end %end of if statement
end %end of while loop
A = Q0ReconstructedRounded; %Reassign to a simpler variable
ICompressed = cell2mat(A); %Reassemble 8x8 blocks into a single 512x512 matrix
FinalImage = uint8(ICompressed); %Converts the file to an 8-bit unsigned
integer
%imshow(I);
%imshow(FinalImage);
%imwrite(FinalImage,'C:\Users\Jonathan\Documents\MATLAB\lena512compressed.jpg'
)

ENGI-4557

Digital Communications 24
JPEG Image Compression

10% Compression (JPEGCompression10.m)


%This breaks a 2 dimensional grayscale image, "lena512.bmp" into 8x8 blocks
%and performs a compression.
n = 1; %set "n" variable to 1
m = 1; %set "m" variable to 1
I = imread('lena512.bmp'); %read in the image
%The ridiculously inefficient line below breaks up the 512x512 grayscale
%image into 8x8 blocks of pixels
P0original = mat2cell(I,[8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8], [8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8]);
while (n <= 64) && (m <= 64) %while loop to analyze each individual 8x8 block
in the image and perform compression based on specified quantization
%matrix, "Q0"
P0{m,n} = P0original{m,n} - 128; %subtracts 128 from each original value
to make it a signed integer (as opposed to unsigned)
P0fDCT{m,n} = roundn(dct2(P0{m,n}), 0); %performs two dimensional
discrete cosine transform to bring values from spatial
%domain into the frequency domain and rounds these values to zero
decimal places
Q90 = [3
2
3
3
4
5
10
14

2
2
3
3
4
7
13
18

2
3
3
4
7
11
16
19

3
4
5
6
11
13
17
20

5
5
8
10
14
16
21
22

8
12
11
17
22
12
24
20

10
12
14
16
21
23
24
20

12;
11;
11;
12;
15;
18;
21;
20];

Q0Norm{m,n} = ldivide(Q90, P0fDCT{m,n}); %Normalization of the matrix


using element-by-element division (left-array-division)
Q0NormRounded{m,n} = roundn(Q0Norm{m,n}, 0); %Simply rounds the
normalized matrix
%At this point, the zig-zag algorithm would be run and process each 8x8
%block into a row vector so that the run-length algorithm can be applied to
%compress the image file for transmission
Q0DeNorm{m,n} = times(Q0NormRounded{m,n},Q90); %Denormalization of the
matrix via element-by-element multiplication
Q0Reconstructed{m,n} = idct2(Q0DeNorm{m,n}); %Performs inverse
discrete cosine transform to bring values back to spatial domain

ENGI-4557

Digital Communications 25
JPEG Image Compression

Q0Reconstructed128{m,n} = Q0Reconstructed{m,n} + 128; %Adds 128 to


each value convert values to unsigned integers
Q0ReconstructedRounded{m,n} = roundn(Q0Reconstructed128{m,n}, 0);
%Rounds each value to zero decimal places

n = n + 1; %Adds one to the n counter


if (n == 65) %'If statement' to allow each block in P0original{m,n} to
be scanned, i.e., from P0original{1,1} to P0original{64,64}
m = m + 1;
n = 1;
end %end of if statement
end %end of while loop
A = Q0ReconstructedRounded; %Reassign to a simpler variable
ICompressed = cell2mat(A); %Reassemble 8x8 blocks into a single 512x512 matrix
FinalImage = uint8(ICompressed); %Converts the file to an 8-bit unsigned
integer
%imshow(I);
%imshow(FinalImage);
%imwrite(FinalImage,'C:\Users\Jonathan\Documents\MATLAB\lena512compressed.jpg'
)

Homepage (Homepage.m)
function varargout = Homepage(varargin)

ENGI-4557

Digital Communications 26
JPEG Image Compression

% HOMEPAGE MATLAB code for Homepage.fig


%
HOMEPAGE, by itself, creates a new HOMEPAGE or raises the existing
%
singleton*.
%
%
H = HOMEPAGE returns the handle to a new HOMEPAGE or the handle to
%
the existing singleton*.
%
%
HOMEPAGE('CALLBACK',hObject,eventData,handles,...) calls the local
%
function named CALLBACK in HOMEPAGE.M with the given input arguments.
%
%
HOMEPAGE('Property','Value',...) creates a new HOMEPAGE or raises the
%
existing singleton*. Starting from the left, property value pairs are
%
applied to the GUI before Homepage_OpeningFcn gets called. An
%
unrecognized property name or invalid value makes property application
%
stop. All inputs are passed to Homepage_OpeningFcn via varargin.
%
%
*See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
%
instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help Homepage
% Last Modified by GUIDE v2.5 24-Nov-2013 15:41:54
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',
mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @Homepage_OpeningFcn, ...
'gui_OutputFcn', @Homepage_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback',
[]);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before Homepage is made visible.


function Homepage_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% varargin
command line arguments to Homepage (see VARARGIN)
% Choose default command line output for Homepage
handles.output = hObject;

ENGI-4557

Digital Communications 27
JPEG Image Compression

% Update handles structure


guidata(hObject, handles);
% UIWAIT makes Homepage wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = Homepage_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes on button press in DCTExample.
function DCTExample_Callback(hObject, eventdata, handles)
run DCTFig
% hObject
handle to DCTExample (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in Lena.


function Lena_Callback(hObject, eventdata, handles)
run DCTLena
% hObject
handle to Lena (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes during object creation, after setting all properties.


function axes4_CreateFcn(hObject, eventdata, handles)
axes(hObject)
imshow('Background.png')
% hObject
handle to axes2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
empty - handles not created until after all CreateFcns called
% Hint: place code in OpeningFcn to populate axes2

DCT Test Using Basis Vectors (DCTTest.m)


%This is an example of an 8x8 block of spatial domain values. Each value
%represents an unsigned integer from 0 - 255 to represent a colour.

ENGI-4557
P0 =

[139
144
150
159
159
161
162
162

144
151
155
161
160
161
162
162

149
153
160
162
161
161
161
161

153
156
163
160
162
161
163
161

155
159
158
160
162
160
162
163

155
156
156
159
155
157
157
158

155
156
156
159
155
157
157
158

Digital Communications 28
JPEG Image Compression

155;
156;
156;
159;
155;
157;
157;
158];

%The line below subtracts 128 from each element in the above matrix to
%make an signed integer to work with for the DCT algorithm.
P = P0 - 128;
%The two lines below are to produce the C(omega) term in Eq. 1.5.
S = eye(8)/2;
S(1,1) = 1/2/sqrt(2);
%Below, the DCT vectors are arranged and then multiplied by S to complete
%equation Eq 1.5.
D = zeros(8,8);
for t = [0:7]
for w = [0:7] %where w is u and v
D(w+1, t+1) = cos((2*t+1)*w*pi/16);
end
end
%Equation Eq. 1.5 therefore is:
D = S * D;
%Perform forward DCT to obtain the 8x8 matrix of DCT coefficients.
F = D * P * D';

GUI For Test Bench First Page (DCTFig.m)


function varargout = DCTFig(varargin)
% DCTFIG MATLAB code for DCTFig.fig
%
DCTFIG, by itself, creates a new DCTFIG or raises the existing
%
singleton*.

ENGI-4557

Digital Communications 29
JPEG Image Compression

%
%
H = DCTFIG returns the handle to a new DCTFIG or the handle to
%
the existing singleton*.
%
%
DCTFIG('CALLBACK',hObject,eventData,handles,...) calls the local
%
function named CALLBACK in DCTFIG.M with the given input arguments.
%
%
DCTFIG('Property','Value',...) creates a new DCTFIG or raises the
%
existing singleton*. Starting from the left, property value pairs are
%
applied to the GUI before DCTFig_OpeningFcn gets called. An
%
unrecognized property name or invalid value makes property application
%
stop. All inputs are passed to DCTFig_OpeningFcn via varargin.
%
%
*See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
%
instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help DCTFig
% Last Modified by GUIDE v2.5 22-Nov-2013 18:57:02
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',
mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @DCTFig_OpeningFcn, ...
'gui_OutputFcn', @DCTFig_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback',
[]);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before DCTFig is made visible.


function DCTFig_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% varargin
command line arguments to DCTFig (see VARARGIN)
% Choose default command line output for DCTFig
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);

ENGI-4557

Digital Communications 30
JPEG Image Compression

% UIWAIT makes DCTFig wait for user response (see UIRESUME)


% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = DCTFig_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes when entered data in editable cell(s) in spatial.


function spatial_CellEditCallback(hObject, eventdata, handles)
P0 = get(hObject,'data');
% hObject
handle to spatial (see GCBO)
% eventdata structure with the following fields (see UITABLE)
%
Indices: row and column indices of the cell(s) edited
%
PreviousData: previous data for the cell(s) edited
%
EditData: string(s) entered by the user
%
NewData: EditData or its converted form set on the Data property. Empty if
Data was not changed
%
Error: error string when failed to convert EditData to appropriate value
for Data
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in showspatial.


function showspatial_Callback(hObject, eventdata, handles)
run JPEGCompression
set(handles.spatial,'Data',P0original);
set(handles.spatial,'ColumnName',{'x1','x2','x3','x4','x5','x6','x7','x8'});
set(handles.spatial,'RowName',{'y1','y2','y3','y4','y5','y6','y7','y8'});
% hObject
handle to showspatial (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% --- Executes on button press in showdctcoefficients.
function showdctcoefficients_Callback(hObject, eventdata, handles)
run JPEGCompression
set(handles.dctcoefficients,'Data',P0fDCT);
set(handles.dctcoefficients,'ColumnName',
{'u1','u2','u3','u4','u5','u6','u7','u8'});
set(handles.dctcoefficients,'RowName',
{'v1','v2','v3','v4','v5','v6','v7','v8'});
% hObject
handle to showdctcoefficients (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in showquant.

ENGI-4557

Digital Communications 31
JPEG Image Compression

function showquant_Callback(hObject, eventdata, handles)


run JPEGCompression
set(handles.quantizationtable,'Data',Q0);
% hObject
handle to showquant (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in normalized.


function normalized_Callback(hObject, eventdata, handles)
run JPEGCompression
set(handles.normalizedtable,'Data',Q0NormRounded);
% hObject
handle to normalized (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in reconstructed.


function reconstructed_Callback(hObject, eventdata, handles)
run JPEGCompression
set(handles.reconstructedtable,'Data',Q0ReconstructedRounded);
set(handles.reconstructedtable,'ColumnName',
{'x1','x2','x3','x4','x5','x6','x7','x8'});
set(handles.reconstructedtable,'RowName',
{'y1','y2','y3','y4','y5','y6','y7','y8'});
% hObject
handle to reconstructed (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in denormalized.


function denormalized_Callback(hObject, eventdata, handles)
run JPEGCompression
set(handles.denormalizedtable,'Data',Q0DeNorm);
% hObject
handle to denormalized (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in zigzag.


function zigzag_Callback(hObject, eventdata, handles)
run JPEGCompression
zigzag(Q0NormRounded);
RLE_encode(ans);
set(handles.runlengthtable,'data',ans);
% hObject
handle to zigzag (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

function runlengthtable_Callback(hObject, eventdata, handles)


% hObject
handle to runlengthtable (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

ENGI-4557

Digital Communications 32
JPEG Image Compression

% Hints: get(hObject,'String') returns contents of runlengthtable as text


%
str2double(get(hObject,'String')) returns contents of runlengthtable
as a double

% --- Executes during object creation, after setting all properties.


function runlengthtable_CreateFcn(hObject, eventdata, handles)
% hObject
handle to runlengthtable (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%
See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end

% --- Executes during object creation, after setting all properties.


function transmission_CreateFcn(hObject, eventdata, handles)
axes(hObject)
imshow('transmission.jpg')
% hObject
handle to transmission (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
empty - handles not created until after all CreateFcns called
% Hint: place code in OpeningFcn to populate transmission

% --- Executes on button press in transmit.


function transmit_Callback(hObject, eventdata, handles)
run DCTFig2
% hObject
handle to transmit (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes when entered data in editable cell(s) in runlengthtable.


function runlengthtable_CellEditCallback(hObject, eventdata, handles)
% hObject
handle to runlengthtable (see GCBO)
% eventdata structure with the following fields (see UITABLE)
%
Indices: row and column indices of the cell(s) edited
%
PreviousData: previous data for the cell(s) edited
%
EditData: string(s) entered by the user
%
NewData: EditData or its converted form set on the Data property. Empty if
Data was not changed
%
Error: error string when failed to convert EditData to appropriate value
for Data
% handles
structure with handles and user data (see GUIDATA)

ENGI-4557

Digital Communications 33
JPEG Image Compression

GUI For Test Bench Second Page (DCTFig2.m)


function varargout = DCTFig2(varargin)
% DCTFIG2 MATLAB code for DCTFig2.fig
%
DCTFIG2, by itself, creates a new DCTFIG2 or raises the existing
%
singleton*.
%
%
H = DCTFIG2 returns the handle to a new DCTFIG2 or the handle to
%
the existing singleton*.
%
%
DCTFIG2('CALLBACK',hObject,eventData,handles,...) calls the local

ENGI-4557

Digital Communications 34
JPEG Image Compression

%
function named CALLBACK in DCTFIG2.M with the given input arguments.
%
%
DCTFIG2('Property','Value',...) creates a new DCTFIG2 or raises the
%
existing singleton*. Starting from the left, property value pairs are
%
applied to the GUI before DCTFig2_OpeningFcn gets called. An
%
unrecognized property name or invalid value makes property application
%
stop. All inputs are passed to DCTFig2_OpeningFcn via varargin.
%
%
*See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
%
instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help DCTFig2
% Last Modified by GUIDE v2.5 22-Nov-2013 19:05:03
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',
mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @DCTFig2_OpeningFcn, ...
'gui_OutputFcn', @DCTFig2_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback',
[]);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before DCTFig2 is made visible.


function DCTFig2_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% varargin
command line arguments to DCTFig2 (see VARARGIN)
% Choose default command line output for DCTFig2
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes DCTFig2 wait for user response (see UIRESUME)
% uiwait(handles.figure1);

ENGI-4557

Digital Communications 35
JPEG Image Compression

% --- Outputs from this function are returned to the command line.
function varargout = DCTFig2_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in zigzag.


function zigzag_Callback(hObject, eventdata, handles)
run JPEGCompression
zigzag(Q0NormRounded);
RLE_encode(ans);
set(handles.runlengthtable,'data',ans);
% hObject
handle to zigzag (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in zigzag.


function zigzag_Callback(hObject, eventdata, handles)
% hObject
handle to zigzag (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes during object creation, after setting all properties.


function transmission_CreateFcn(hObject, eventdata, handles)
axes(hObject)
imshow('transmission.jpg')
% hObject
handle to transmission (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
empty - handles not created until after all CreateFcns called
% Hint: place code in OpeningFcn to populate transmission

% --- Executes on button press in reconstructed.


function reconstructed_Callback(hObject, eventdata, handles)
run JPEGCompression
set(handles.reconstructedtable,'Data',Q0ReconstructedRounded);
set(handles.reconstructedtable,'ColumnName',
{'x1','x2','x3','x4','x5','x6','x7','x8'});
set(handles.reconstructedtable,'RowName',
{'y1','y2','y3','y4','y5','y6','y7','y8'});
% hObject
handle to reconstructed (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

ENGI-4557

Digital Communications 36
JPEG Image Compression

GUI for Lena First Page (DCTLena.m)


function varargout = DCTLena(varargin)
% DCTLENA MATLAB code for DCTLena.fig
%
DCTLENA, by itself, creates a new DCTLENA or raises the existing
%
singleton*.
%
%
H = DCTLENA returns the handle to a new DCTLENA or the handle to
%
the existing singleton*.
%
%
DCTLENA('CALLBACK',hObject,eventData,handles,...) calls the local
%
function named CALLBACK in DCTLENA.M with the given input arguments.

ENGI-4557

Digital Communications 37
JPEG Image Compression

%
%
DCTLENA('Property','Value',...) creates a new DCTLENA or raises the
%
existing singleton*. Starting from the left, property value pairs are
%
applied to the GUI before DCTLena_OpeningFcn gets called. An
%
unrecognized property name or invalid value makes property application
%
stop. All inputs are passed to DCTLena_OpeningFcn via varargin.
%
%
*See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
%
instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help DCTLena
% Last Modified by GUIDE v2.5 22-Nov-2013 23:07:51
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',
mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @DCTLena_OpeningFcn, ...
'gui_OutputFcn', @DCTLena_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback',
[]);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before DCTLena is made visible.


function DCTLena_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% varargin
command line arguments to DCTLena (see VARARGIN)
% Choose default command line output for DCTLena
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes DCTLena wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.

ENGI-4557

Digital Communications 38
JPEG Image Compression

function varargout = DCTLena_OutputFcn(hObject, eventdata, handles)


% varargout cell array for returning output args (see VARARGOUT);
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in OriginalValues.


function OriginalValues_Callback(hObject, eventdata, handles)
run JPEGCompressionGrayscale
set(handles.OriginalImage,'Data',I);
% hObject
handle to OriginalValues (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in NextLena.


function NextLena_Callback(hObject, eventdata, handles)
run DCTLena2
% hObject
handle to NextLena (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

GUI For Lena Second Page (DCTLena2.m)


function varargout = DCTLena2(varargin)
% DCTLENA2 MATLAB code for DCTLena2.fig
%
DCTLENA2, by itself, creates a new DCTLENA2 or raises the existing
%
singleton*.
%
%
H = DCTLENA2 returns the handle to a new DCTLENA2 or the handle to
%
the existing singleton*.
%
%
DCTLENA2('CALLBACK',hObject,eventData,handles,...) calls the local
%
function named CALLBACK in DCTLENA2.M with the given input arguments.
%

ENGI-4557

Digital Communications 39
JPEG Image Compression

%
DCTLENA2('Property','Value',...) creates a new DCTLENA2 or raises the
%
existing singleton*. Starting from the left, property value pairs are
%
applied to the GUI before DCTLena2_OpeningFcn gets called. An
%
unrecognized property name or invalid value makes property application
%
stop. All inputs are passed to DCTLena2_OpeningFcn via varargin.
%
%
*See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
%
instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help DCTLena2
% Last Modified by GUIDE v2.5 24-Nov-2013 12:49:16
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',
mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @DCTLena2_OpeningFcn, ...
'gui_OutputFcn', @DCTLena2_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback',
[]);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before DCTLena2 is made visible.


function DCTLena2_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% varargin
command line arguments to DCTLena2 (see VARARGIN)
% Choose default command line output for DCTLena2
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes DCTLena2 wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = DCTLena2_OutputFcn(hObject, eventdata, handles)

ENGI-4557
%
%
%
%

varargout
hObject
eventdata
handles

Digital Communications 40
JPEG Image Compression

cell array for returning output args (see VARARGOUT);


handle to figure
reserved - to be defined in a future version of MATLAB
structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure


varargout{1} = handles.output;

% --- Executes on button press in blockvalues.


function blockvalues_Callback(hObject, eventdata, handles)
run JPEGCompressionGrayscale
m = str2double(get(handles.uvalue, 'String'));
n = str2double(get(handles.vvalue, 'String'));
set(handles.viewtable,'Data',P0original{m,n});
set(handles.viewtable,'ColumnName',{'x1','x2','x3','x4','x5','x6','x7','x8'});
set(handles.viewtable,'RowName',{'y1','y2','y3','y4','y5','y6','y7','y8'});
% hObject
handle to blockvalues (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

function uvalue_Callback(hObject, eventdata, handles)


% hObject
handle to uvalue (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of uvalue as text
%
str2double(get(hObject,'String')) returns contents of uvalue as a
double

% --- Executes during object creation, after setting all properties.


function uvalue_CreateFcn(hObject, eventdata, handles)
% hObject
handle to uvalue (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%
See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end

function vvalue_Callback(hObject, eventdata, handles)


% hObject
handle to vvalue (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of vvalue as text

ENGI-4557
%
double

Digital Communications 41
JPEG Image Compression

str2double(get(hObject,'String')) returns contents of vvalue as a

% --- Executes during object creation, after setting all properties.


function vvalue_CreateFcn(hObject, eventdata, handles)
% hObject
handle to vvalue (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%
See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in dctcoefficients.


function dctcoefficients_Callback(hObject, eventdata, handles)
run JPEGCompressionGrayscale
m = str2double(get(handles.uvalue, 'String'));
n = str2double(get(handles.vvalue, 'String'));
set(handles.viewtable,'Data',P0fDCT{m,n});
set(handles.viewtable,'ColumnName',{'u1','u2','u3','u4','u5','u6','u7','u8'});
set(handles.viewtable,'RowName',{'v1','v2','v3','v4','v5','v6','v7','v8'});
% hObject
handle to dctcoefficients (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in normalized.


function normalized_Callback(hObject, eventdata, handles)
run JPEGCompressionGrayscale
m = str2double(get(handles.uvalue, 'String'));
n = str2double(get(handles.vvalue, 'String'));
set(handles.viewtable,'Data',Q0NormRounded{m,n});
set(handles.viewtable,'ColumnName',{'u1','u2','u3','u4','u5','u6','u7','u8'});
set(handles.viewtable,'RowName',{'v1','v2','v3','v4','v5','v6','v7','v8'});
% hObject
handle to normalized (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in reconstructed.


function reconstructed_Callback(hObject, eventdata, handles)
run JPEGCompressionGrayscale
m = str2double(get(handles.uvalue, 'String'));
n = str2double(get(handles.vvalue, 'String'));
set(handles.viewtable,'Data', A{m,n});
set(handles.viewtable,'ColumnName',{'x1','x2','x3','x4','x5','x6','x7','x8'});
set(handles.viewtable,'RowName',{'y1','y2','y3','y4','y5','y6','y7','y8'});
% hObject
handle to reconstructed (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

ENGI-4557

Digital Communications 42
JPEG Image Compression

% --- Executes on button press in ShowOriginal.


function ShowOriginal_Callback(hObject, eventdata, handles)
run JPEGCompressionGrayscale
guidata(hObject, handles);
axes(handles.Original);
imshow(I)
% hObject
% eventdata
% handles

handle to ShowOriginal (see GCBO)


reserved - to be defined in a future version of MATLAB
structure with handles and user data (see GUIDATA)

% --- Executes on button press in ShowCompressed.


function ShowCompressed_Callback(hObject, eventdata, handles)
run JPEGCompressionGrayscale
guidata(hObject, handles);
axes(handles.Compressed);
imshow(FinalImage)
% hObject
handle to ShowCompressed (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in save.


function save_Callback(hObject, eventdata, handles)
run JPEGCompressionGrayscale
imwrite(FinalImage,'C:\Users\Jonathan\Desktop\lenacompressed.jpg')
% hObject
% eventdata
% handles

handle to save (see GCBO)


reserved - to be defined in a future version of MATLAB
structure with handles and user data (see GUIDATA)

% --- Executes on button press in tenpercent.


function tenpercent_Callback(hObject, eventdata, handles)
run JPEGCompression10
guidata(hObject, handles);
axes(handles.Compressed);
imshow(FinalImage)
% hObject
handle to tenpercent (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in ninetypercent.


function ninetypercent_Callback(hObject, eventdata, handles)
run JPEGCompression90
guidata(hObject, handles);
axes(handles.Compressed);
imshow(FinalImage)
% hObject
handle to ninetypercent (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

ENGI-4557

Digital Communications 43
JPEG Image Compression

% --- Executes on button press in saveoriginal.


function saveoriginal_Callback(hObject, eventdata, handles)
run JPEGCompressionGrayscale
imwrite(I,'C:\Users\Jonathan\Desktop\lenaoriginal.jpg')
% hObject
handle to saveoriginal (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in showoriginalsize.


function showoriginalsize_Callback(hObject, eventdata, handles)
DirInfo1 = dir('C:\Users\Jonathan\Desktop\lenaoriginal.jpg');
filesize1 = DirInfo1.bytes
msgbox(['The size of this file in JPEG format is: ' num2str(filesize1) '
bytes'], 'Filesize');
% hObject
handle to showoriginalsize (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in showcompressedsize.


function showcompressedsize_Callback(hObject, eventdata, handles)
DirInfo2 = dir('C:\Users\Jonathan\Desktop\lenacompressed.jpg');
filesize2 = DirInfo2.bytes
msgbox(['The size of this file in JPEG format is: ' num2str(filesize2) '
bytes'], 'Filesize');
% hObject
handle to showcompressedsize (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

% --- Executes on button press in saveoriginal.


function saveoriginal_Callback(hObject, eventdata, handles)
% hObject
handle to saveoriginal (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)

ENGI-4557

Digital Communications 44
JPEG Image Compression

ENGI-4557

Digital Communications 45
JPEG Image Compression

Zig Zag Transform for Quantized, Rounded Matrix (zigzag.m)


function output = zigzag(in)
%Receives a matrix of even and equal length and width and outputs an array
%of the values ordered in a zig-zag pattern. This is required for the run
%length encoding in order to group the zero values from the bottom right of
%the matrix into sequential entries in the array
% initializing the xariables
%---------------------------------y = 1;
x = 1;
%start points
xmin = 1;
ymin = 1;
%maximum length
xmax = size(in,
%maximum length
ymax = size(in,

of X axis (dimension 1)
1);
of Y axis (dimension 2)
2);

i = 1;
%initializes a 1-dimensional matrix (vector) with length = the size of our
%imput matrix
output = zeros(1, xmax * ymax);
%---------------------------------%
%
%
%
%
%
%

+-----> +Y
|
|
|
V
+X

%Output element i = the starting point in(1,1)


output(i) = in(x, y);
%until the end of the matrix
while ((x <= xmax) && (y <= ymax))
%===Upwards Direction===
%points where x+y = a multiple of 2
if (mod(y + x, 2) == 0)
if (x == xmin)
%CASE A: upper-right point in the matrix => move down-left
if (y == ymax)
x = x + 1;
y = y - 1;
%CASE B: top row, anywhere else => move right
else

ENGI-4557

Digital Communications 46
JPEG Image Compression

y = y + 1;
end;
%CASE C: last column but not max row => move down
elseif ((y == ymax) && (x < xmax))
x = x + 1;
%CASE D: all other cases => move up-right
elseif ((x > xmin) && (y < ymax))
x = x - 1;
y = y + 1;
end;
%===Downwards Direction===
else %points where x+y != a multiple of 2
%CASE E: bottom row => move right
if (x == xmax)
y = y + 1;
%CASE F: first column, any row but first
elseif (y == ymin && x < xmax)
x = x + 1;
%CASE G: all other cases => move down-left
elseif ((x < xmax) && (y > ymin))
% all other cases
x = x + 1;
y = y - 1;
end;
end;
%increment i to add the next element to output array
i = i + 1;
%Output element i = the current point in the matrix in(x,y)
output(i) = in(x, y);
%CASE I: bottom-right corner => break loop
if ((x == xmax) && (y == ymax))
output(i) = in(x, y);
break
end;
end;

ENGI-4557

Digital Communications 47
JPEG Image Compression

Run Length Encoding for Zig Zag Transformed Image


(RLE_encode.m)
function encoded = RLE_encode(input)
%Receives an input array of values and outputs a compressed array using run
%length encoding. Sequential entries are put into an output array in pairs
%[i, j], where i represents the numerical value of the entry and represents
%the number of times it appears, sequentially.
%get length = the length of the input vector
length = size(input,2);
%by default, set run_length to 1
run_length = 1;
%initialize empty array for encoded output
encoded = [];
%for the whole vector
for i=2:length
%look back at previous entry and check equivalence
if input(i) == input(i-1)
%increment run_length if they are equal
run_length = run_length + 1;
else
%push value and run length into encoded output vector if they are
%not equal
encoded = [encoded input(i-1) run_length];
run_length = 1;
end
end
if length > 1
% Add last value and run length to output
encoded = [encoded input(i) run_length];
else
% Special case if input is of length 1
encoded = [input(1) 1];
end

ENGI-4557

Digital Communications 48
JPEG Image Compression

Run Length Decoding for Received Encoded Image


(RLE_decode.m)
function decoded = RLE_decode(encoded)
%Receives a run length encoded array and outputs an expanded array using
%run length decoding. For every pair of entries in the input array [i, j]
% i represents the numerical value of an entry in the output array and j
% represents the number of times it is sequentially shown.
%i.e. [8,4] is decoded to make [8, 8, 8, 8]
my_size = size(encoded);
length = my_size(2);
index = 1;
decoded = [];
% iterate through the input
while (index <= length)
% get value which is followed by the run count
value = encoded(index);
run_length = encoded(index + 1);
for i=1:run_length
% loop adding 'value' to output 'run_length' times
decoded = [decoded value];
end
% put index at next value element (odd element)
index = index + 2;
end

ENGI-4557

Digital Communications 49
JPEG Image Compression

Inverse Zig Zag Function for Decoded Image (invzigzag.m)


function out=invzigzag(in)

%Receives an input array of 64 entries and outputs an 8x8 matrix (as


%required by our project). Entries are read from the input array and
%inserted in a zig - zag pattern in order to reconstruct the image before
%the encoding process

%Our code uses blocks of 8x8 pixels while encoding


num_rows = 8;
num_cols = 8;
tot_elem=length(in);
% Check if matrix dimensions correspond
if tot_elem~=num_rows*num_cols
error('Matrix dimensions do not coincide');
end
% Initialise the output matrix to be the the size of the rows x columns
out=zeros(num_rows,num_cols);
cur_row=1;
cur_col=1;
cur_index=1;
% First element
%out(1,1)=in(1);
while cur_index<=tot_elem
if cur_row==1 && mod(cur_row+cur_col,2)==0 && cur_col~=num_cols
out(cur_row,cur_col)=in(cur_index);
cur_col=cur_col+1;
%move right at the top
cur_index=cur_index+1;
elseif cur_row==num_rows && mod(cur_row+cur_col,2)~=0 && cur_col~=num_cols
out(cur_row,cur_col)=in(cur_index);
cur_col=cur_col+1;
%move right at the bottom
cur_index=cur_index+1;
elseif cur_col==1 && mod(cur_row+cur_col,2)~=0 && cur_row~=num_rows
out(cur_row,cur_col)=in(cur_index);
cur_row=cur_row+1;
%move down at the left
cur_index=cur_index+1;
elseif cur_col==num_cols && mod(cur_row+cur_col,2)==0 && cur_row~=num_rows
out(cur_row,cur_col)=in(cur_index);
cur_row=cur_row+1;
%move down at the right

ENGI-4557

Digital Communications 50
JPEG Image Compression

cur_index=cur_index+1;
elseif cur_col~=1 && cur_row~=num_rows && mod(cur_row+cur_col,2)~=0
out(cur_row,cur_col)=in(cur_index);
cur_row=cur_row+1;
cur_col=cur_col-1; %move diagonally left down
cur_index=cur_index+1;
elseif cur_row~=1 && cur_col~=num_cols && mod(cur_row+cur_col,2)==0
out(cur_row,cur_col)=in(cur_index);
cur_row=cur_row-1;
cur_col=cur_col+1; %move diagonally right up
cur_index=cur_index+1;
elseif cur_index==tot_elem
element
out(end)=in(end);
break
end
end

%input the bottom right


%end of the operation
%terminate the operation

Appendix B MATLAB Graphical User Interfaces

ENGI-4557

Tag: showspatial

Digital Communications 51
JPEG Image Compression

Tag:
showdctcoefficients

Tag: showquant

Tag: transmit

Tag: zigzag
Tag: normalized

Tag: zigzag

Tag: reconstructed

ENGI-4557

Digital Communications 52
JPEG Image Compression

Tag: OriginalValues

Tag: tenpercent

Tag:
ShowCompressed

Tag: blockvalues
Tag: ninetypercent

Tag: dctcoefficients

Tag: ShowOriginal

Tag: chrominance50

Tag: normalized
Tag: save
Tag: reconstructed
Tag:
showcompressedsize

ENGI-4557

Digital Communications 53
JPEG Image Compression

Works Cited
[1] MathWorks. [Online]. www.mathworks.com
[2] Gregory K. Wallace, "The JPEG Still Picture Compression Standard," Maynard,
Massechusetts, 1992.
[3] Andrew B. Watson, "Image Compression Using the Discrete Cosine Transform," NASA
Ames Research Centre, 1994.
[4] "JPEG Baseline Sequential Codec," XIL Programmer's Guide, 1994.
[5] "Terminal Equipment and Protocols for Telematic Services: Information Technology Digital Compression and Coding of Continuous-Tone Still Images-Requirements and
Guidelines," International Telecommunication Union, 1992.
[6] Peter Gent Ken Cabeen, "Image Compression and the Discrete Cosine Transform," College
of the Redwoods,.
[7] Stanislav Hanus Tomas Fryza, "Image Compression Algorithms Optimized for MATLAB,"
Brno University of Technology, Purkynova, Czech Republic,.