You are on page 1of 33

Wavelet Image Compression on the DSP

EE113D Final Project, Spring 2007


Csaba Petre and Vineet Varma
Introduction and Theory:

The objective of our project was to perform the discrete Haar wavelet transformation
on an image for the purpose of compression. The Haar wavelet transformation is
composed of a sequence of low-pass and high-pass filters, known as a filter bank.
These filter sequences can be applied in the same way as a discrete FIR filter in the
DSP, using the MACP command, except as multiple successive FIR filters. The low
pass filter performs an averaging/blurring operation, and is expressed as:
1
H= ( 1,1)
2
and the high-pass filter performs a differencing operation and can be expressed as:
1
G= ( 1, -1)
2
on any adjacent pixel pair. The complete wavelet transform can be represented in
matrix format by:

Second half: Applying 1D


Transformation to Columns of Image

T = WN AWNT

First half: Applying 1D


Transformation to Rows of Image

where A is the matrix representing the 2D image pixels, T is the Haar wavelet
transformation of the image, and

1 1
2 0 0 0 0 0 0
2

1 1
0 0
2 2
0 0 0 0

0 1 1
0 0 0 0 0

2 2

0 1 1
0 0 0 0 0
H 2 2
WN = =
G 1 1
- 0 0 0 0 0 0
2 2

0 1 1
0 - 0 0 0 0
2 2

0 1 1
0 0 0 - 0 0
2 2

0 1 1
0 0 0 0 0 -

2 2

in the case of transforming a 4x4 pixel image. The equivalent matrix can be expanded
for larger images. This transformation can be represented by an FIR filter approach
for use with the DSPs MACP operation. We will discuss this in more detail later.

The result of the complete transformation, T, is composed of 4 new sub-images,


which correspond to the blurred image, and the vertical, diagonal, and horizontal
differences between the original image and the blurred image. The blurred
representation of the image removes the details (high frequency components), which
are represented separately in the other three images, in a manner that produces a
sparser representation overall, making it is easier to store and transmit. Below is an
example of a wavelet transformed image portraying the four sub-images as explained
above.

The inverse transformation can be applied to T, resulting in lossless compression.


Lossy compression can be implemented by manually setting to zero the elements
below a certain threshold in T. The equation of the inverse transformation is:

A%= WN-1TWN-T ( = A after lossless compression)

In assembly, we implemented the matrix multiplication using a filter representation of


the process. We first applied the filter G and H over the rows and then the columns as
an FIR filter. While performing this step we use a technique called downsampling to
prevent redundancies. As will be demonstrated later, we need to work with only
successive pairs of elements. To perform this process, we throw away every other
result and keep only the ones obtained from successive pairs of elements. Below is an
explanatory diagram of the mechanism of the filter application (first half). A similar
process is used for the second half of the transformation:
Downsampling:
Apply G over first Delay 0
column of image with Second column, third Delay 2
downsampling column, etc
Delay 4

WN A =
Delay 0
Apply H over first Second column, third Delay 2
column of image with
column, etc Delay 4
downsampling

The wavelet transformation employs the use of a technique called averaging and
differencing. Below is a simple example of the technique performed on a single row
of the matrix of pixels that represent an image.

Imagine extracting one row from a 16x16 black and white, 256-color image in its
matrix form. For example:

Original Sequence:
45 45 46 46 47 48 53 101 104 105 106 106 107 106 106 106

Every element in this 16-element vector has a value between 0 and 255 since the
image is 256-color. The magnitude of the element represents the brightness of its
corresponding pixel. Hence, the darker it is, the closer it is to black (0).

Inside most of the pixel sequence, we notice that most of the elements have values
very close to the values of their neighbors this indicates a gradual shift in color.
Sudden jumps in values occur at the outlines (edges) of objects in the image (53 to
101), which are sudden transitions in brightness.

We also know that any two numbers can be completely characterized by their average
and their difference. In the sequence above, the averages and differences of successive
pairs are:

Averages:
45 46 47.5 77 105 106 107 106

Differences:
0 0 -1 -48 -1 0 1 0

Now, we observe that the sequence of differences has many small (recall that
neighboring values are very similar, implying small differences). This sequence is
therefore very easy to compress. We perform the compression by making all the
values of small magnitude 0. Hence we have a very sparse sequence.

Differences (with threshold):


0 0 0 -48 0 0 0 0

This sequence is highly compressible. Using this new sequence of differences and the
same sequence of averages, we can easily recompute the original sequence that
defined a section of the image:

Recovered Sequence:
45 45 46 46 47 47 53 101 104 104 106 106 106 106 106 106

This is a very good approximation of our original sequence.

To perform the transformation in DSP we loaded the pixel values for the image into
DSP memory, process the image in the DSP assembly program, and output the
transformed image, or transformed-compressed image, to a memory location below
the original image. This data would be processed again to recover the original image.
To be more specific, our original image was loaded at location 0x1800, the
intermediate result, which is the first half of the transformation is stored immediately
below the original image at location 0x1C00. Finally, we store the final output
directly below this at address 0x2000. Below is a memory map showing the addresses
used in the memory for the intermediate result and final result of our output:

Memory Storage Map

Original Image A A
1800 Hex Grayscale Values

Intermediate Result B B = WN A
1C00 Hex Grayscale Values

Transformed Image T T = BWNT


2000 Hex Grayscale Values

Project Development:

Week 1: Research and Wavelet Reviewing

In this first week, we educated ourselves on the theory of wavelet transformations, a


subject neither of us had encountered previously. We also gathered many reports and
other documents that we believed would help us in our project. During the week, we
read these reports and discussed aspects of the reports that could be adapted to the
objective of our project.

Week 2: MATLAB coding

By the second week, we were well versed with the process of the transformation. Our
goal now was to successfully perform the Haar wavelet transformation of a sample
image in MATLAB. If successful, we expected to see the image in the compressed,
yet lossless form. We imposed no restrictions on the complexity of functions used,
since at this stage all we wanted was to see a result. All our programming at this stage
was in MATLAB. At first we used the various functions to perform the matrix
multiplications. Once successful, we broke down the MATLAB functions that we
used into computations into code that could easily be transferred to assembly
language. The most important process here was the conversion of the matrix
multiplication into a filter representation. We also recreated the MACP command in
MATLAB; this would prove very helpful in the following week when we begin to
convert our MATLAB code to assembly.

Week 3: Assembly Coding First half.

After the success of the MATLAB program, we immediately began to rewrite our
code in assembly. Progress slowed down dramatically at this stage, given the many
restrictions and the complexity of programming in assembly. To test our program at
each stage, we performed only the first half of the filter representation of the matrix
multiplication during this week. We constantly compared our results with the results
obtained from performing only the first half of the transformation in MATLAB. This
way we believed that the time spent debugging the program at a later date would be
reduced significantly. Fortunately, progress was satisfactory in this week, and we were
able to move on to the second half of the transformation in the following week.

Week 4: Assembly Coding Second half and Debugging

By this stage in the timeline, we were quite confident of our programming skills in
assembly. We identified errors more quickly, which made the programming less
frustrating. Nonetheless, our progress was always fraught with unexpected and
sometimes arbitrary errors that required much time to correct, mostly by using brute
force. We had a major problem running our code right through. To check our results,
we had to break through the code in code explorer. Because of this problem, our
progress began to crawl. Due to this, we realized that we would not be able to achieve
our initial objective of performing lossless and lossy compression in assembly. We
had also hoped to perform the inverse transformation in assembly. We decided to
pursue only lossless compression because doing this would in itself demonstrate the
capabilities of compression using the wavelet transform. Finally, we realized that the
pipelining of operations was the cause of our inability to run the code in entirety. To
solve this problem, we inserted multiple nop commands after nearly every line of the
code. After this, we successfully got our result and verified it in MATLAB. We also
transferred the hex data from the memory to MATLAB, and performed the inverse
transformation to recover the original, lossless image.

Week 5: Presentation

During this week, we gathered our results and compiled a report of them that was then
transferred to a presentation that was used in class. We reviewed the details of the
wavelet transformation so that we could educate the rest of the class on it too before
demonstrating the results of our project during the presentation.

Discussion of Results:

We were able to successfully perform the Haar wavelet transform for image
compression in Matlab and also on DSP. In Matlab, the forward and inverse
transformation ran as desired and was tested for several different test images. Two
different forward transformations were tested in Matlab; the original matrix
representation of the transformation and its inverse, and the forward transformation as
represented by filter operations on the rows and columns, which is a closer model of
the algorithm used on the DSP. Both representations obtained identical results for the
forward transformation. Two examples tested are shown below, with the original
image on the left and the transformed image on the right, and their sizes as JPEG files
below.

Thus the MATLAB code successfully performed the Haar wavelet transform over the
rows and columns of the image and found the transform T of the image, representing
the transformation:

T = WN AWNT

The inverse transformation using the matrix equation,

A = W N-1TWN-T

recovered the original test image without any changes, showing that the lossless
transformation was implemented correctly.

We implemented only the forward transformation on the DSP, due to time limitations.
We were not able to use the test images above to test our algorithm due to the smaller
memory capacity of the DSP. We were only able to use images of size 32x32. We
tested our DSP code for one particular 32x32 test image, and we compared the
resulting transformed image with the transformation as done using our MATLAB
code. We also compared the result of the inverse transformation on both transformed
images. The results are shown in the diagram below.

It is clear that the DSP successfully performed the lossless Haar wavelet transform on
the sample image correctly. There is some difference in compressed image size, due to
the limited 16-bit precision of computations on the DSP. However, despite this lack of
precision equivalent to Matlabs transform, the inverse transformation yielded images
that were not recognizably different from the original image. Thus, any error
introduced by the limited precision of calculation on the DSP does not actually affect
the accuracy of the transformation in any significant way.

We faced some issues with running the code on the DSP. Debugging various errors
took a significant portion of our development time. One particular problem we
encountered had to do with pipelining of operations. Portions of the code would work
perfectly when we step through line by line, but the program would not run correctly
when we try to run it from beginning to end, or even continuously between certain
breakpoints. We found that the solution was to place NOP commands between lines,
and even multiple NOP commands between some lines. This command tells the DSP
processor to halt processing for one cycle, to allow operations to catch up and the
correct computation results to be used in subsequent commands. Our code ran
flawlessly after this correction. The NOP command, of course, will slow the overall
performance of the code, but our algorithm was not meant to run continuously since it
does not operate on time-domain signals. We noticed no slowdown since it only runs
once. Another issue involved the limitation of how values can be assigned to registers
and accumulators. A seemingly simple command like adding two memory addresses
and setting the resulting memory location to an accumulator value is actually a
somewhat complex command to implement correctly in assembly code. It took time
to find workarounds for unforeseen issues such as these. Thus, in the end we only had
time to implement the lossless forward transform on the DSP, and not the lossy
transform or the inverse transform.

Conclusion:
We successfully implemented the 2-dimensional Haar wavelet transformation on the
DSP as applied to lossless image compression. We also implemented the
transformation and its inverse in Matlab and compared the results to verify that our
algorithm was working correctly. We found that compression on the DSP actually
worked, as we achieved smaller JPEG file sizes for the transformed images when
compared to file sizes for the original images, and we were able to fully recover the
original image from these compressed images using Matlab. Challenges and problems
included memory limitation of the DSP, assembly language issues, and automatic
pipelining of processing. Future extensions of this project could include
implementation of the inverse transform on DSP, and implementation of lossy image
compression by setting a threshold value for the transformed image.

References:

Cheng, H, Huang, Z., Kumimoto, M. Final Project Report Image Processing


Techniques, Spring 2006, <http://mkumimoto.bol.ucla.edu/>

Mulcahy, C. Image compression using the Haar wavelet transform, Spelman


Science and Math Journal, pp. 22-31,
<http://www.cs.toronto.edu/~arnold/320/Readings/haarWavelets.pdf>

Texas Instruments, Application Report SPRA800, Wavelet Transforms in the


TMS320C55x, January 2002,
<http://focus.ti.com/dsp/docs/dspsupporttechdocsc.tsp?
sectionId=3&tabId=409&abstractName=spra800>

Valens, C. A Really Friendly Guide to Wavelets, 1999-2004,


<http://perso.orange.fr/polyvalens/clemens/wavelets/wavelets.html#section4>

Van Fleet, P. Discrete Haar Wavelet Transforms, PREP Wavelet Workshop 2006,
June 7, 2006,
<http://cam.mathlab.stthomas.edu/wavelets/pdffiles/UST06/Lecture4.pdf>

Yusof, Z., Manap, N., Suleiman, I., Saleh, S., Aspar, Z. Impelementation of Wavelet
Codec by using Texas Instruments DSP TMS320C6701 EVM Board,
International Symposium on Signal Processing and its Applications, August
13-16, 2001.

Project Files:

original.jpg:
This is the input image file that will be compressed.

ee113filters.m:
This MATLAB program takes the original input image original.jpg, performs the
wavelet transform on it, and saves the transformed, compressed representation of the
image to transformed_image.jpg.

32.asm:
This file holds the values of the pixels of the image in vector form. These values will
be read by wavelet.asm using the table look-up method.

32noword.asm:
This file is the same as 32.asm, only without the .word directives. This file will is
used by output.m.

8tap.asm:
This file holds the two coefficients of each the two filters that will be used in the
filters in wavelet.asm.

wavelet.asm:
This is the main assembly program file. This program retrieves filter and image
content from 8tap.asm and 32.asm respectively. It then outputs the compressed form
of the image to memory location 0x2000 of the DSP memory.

dsp_output.dat:
This data file contains the output of memory location 0x2000 of the DSP obtained
after running wavelet.asm. The memory, starting at 0x2000, holds the pixel values of
the image that is in the compressed form.

output.m:
This MATLAB program converts the raw data from dsp_output.dat to an image form.
It then displays the original image (using 32noword.asm), the image in compressed
form and the recovered image for comparison.

Code:

wavelet.asm:

.title "Image Compression using Wavelet Transform"


.width 80
.length 55
.mmregs

.setsect ".data", 0x07EF, 0 ;all program code, FIR coeffs and temp
data stored in first block
.setsect ".text", 0x0180, 0 ;of program memory
.setsect "coeff", 0x07F8, 0

.setsect "pic" , 0x1800, 0 ;pictures will be stored in second block of


program memory
.setsect "OPpic", 0x1C00, 0

.sect "pic"
picbeg
.copy "32.asm" ;original pic, loaded as array of 8bit
luminance values

.sect "OPpic"
pic2 ;label for output picture

.sect "coeff"
.copy "8tap.asm" ; 2-tap wavelet FIR
; coefficient values here

.data ; data section where


; intermediate results of the
; calculations will be stored

XN .word 0,0,0,0,0,0,0
XNLAST .word 0 ;
OUTPUT .word 0 ; extra word for the bit bucket

.text ; main program section

**********SET CONSTANTS HERE************


size .set 400h ;set pic size = N^2
ntaps .set 2 ;num taps
lag .set 4 ;num pixels behind input (to store average in 'middle')

ncols .set 32 ;num pixels per row


nrows .set 32 ;num pixels per col
halfn .set 16
****************************************

;WHAT FOLLOWS IS SECOND PART (?) C = WN *


B^T
start:

AR5 = #0 ;AR5 holds current column (array indexing)


AR6 = #(ncols - 1) ;counter to loop through each row

new:
;DP = #XNLAST ;data ptr to allow buffer access

*********************FIRST PART HERE:***************

colp AR2 = #(halfn - 1) ;num times to loop in col (nrows?)


AR1 = #picbeg ;AR1 (input pointer) set to beginning of
pic

*******initialize the input/output pointers*****


B = AR5 ;init input ptr

nop
nop
nop
nop

A = AR1 ;(this setup specific to ncols = 32)

nop
nop
nop
nop

B=B+A ;add to beg of pic to get


AR1 = B ;beginning of column

nop
nop
nop
nop

B = B + #size ;setup output ptr


AR3 = B ;one full size ahead of input to place after
original pic in memory

nop
nop
nop
nop

;situation:
;AR2 is 32
;AR6 is counter
;AR1 is beginning of current input column
;AR3 is beginning of current output column
;AR5 is column number for next column
;AR0, AR4, AR7 unused

********move down each column and compute h1/h2 filters******


AR4 = #0 ;index variable

nop
nop
nop
nop

aloop ;loop through each pixel


; *AR1, *AR1 + 1 are current pixels right now
;FIR code goes here
;A first input pixel

*******FIR CODE****************
;AR0, AR7 unused
;B(index, c) = macd([A(r,c) A(r+1,c)],h1);
;index = index+1;

B = #0 ;n-pixels

nop
nop
nop
nop

AR7 = #2020h ;sets *AR7 to first of *AR1

nop
nop
nop
nop

A = *AR1

nop
nop
nop
nop

*AR7+ = A

nop
nop
nop
nop

A = #0 ;sets A to AR1+32

nop
nop
nop
nop

B = AR1

nop
nop
nop
nop

A = A+B

nop
nop
nop
nop

A = A+#32

nop
nop
nop
nop

AR0 = A

nop
nop
nop
nop

A = *AR0

nop
nop
nop
nop

*AR7+ = A

nop
nop
nop
nop

A = *AR7-

nop
nop
nop
nop

A = *AR7-

nop
nop
nop
nop
B = #0

nop
nop
nop
nop

repeat(#ntaps - 1)
MACP(*AR7+, h0, B)

nop
nop

nop

B = B >> 10

nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop

nop
nop
;RIGHT NOW WHERE WE ARE: above, made MACP
work with one element in row above another for this case
;MUST CHANGE this!!!!! below - not AR3+AR4
; have to be AR3 + AR4*32 = <<5
;store into output - MEMORY ADDRESSING
;must store B to column which starts at AR3
;row of AR4
;memory location is going to be
;AR3+AR4*32
;have A, AR0, AR7

AR7 = B

nop
nop
nop
nop

A = AR3

nop
nop
nop
nop

B = AR4

nop
nop
nop
nop

AR0 = B

nop
nop
nop
nop

B = B << 5

nop
nop
nop
nop

A = A+B

nop
nop
nop
nop

AR0 = A

nop
nop
nop
nop

A = AR7

nop
nop
nop
nop
nop
nop
nop

*AR0 = A

nop
nop
nop
nop

A = AR4

nop
nop
nop
nop

A = A + #1 ;increments index

nop
nop
nop
nop

AR4 = A

nop
nop
nop
nop

A = AR1

nop
nop
nop
nop

A = A + #64

nop
nop
nop
nop

AR1 = A
*******************************
nop
nop
nop
nop

;increment current pixel again (total by 2)

;B = *AR2-
if(*AR2- != 0) goto aloop ;if pixels remaining continue

*************************************************************

nop
nop
nop
nop

AR2 = #(halfn - 1) ;num times to loop in row (ncols?)


AR1 = #picbeg ;AR1 (input pointer) set to beginning of
pic

nop
nop
nop
nop

B = AR5 ;init input ptr

nop
nop
nop
nop

nop

A = AR1 ;(this setup specific to ncols = 32)

nop
nop
nop
nop

B=B+A ;add to beg of pic to get

nop
nop
nop

AR1 = B ;beginning of row

nop
nop
nop
nop

B = B + #size ;setup output ptr

nop
nop
nop

AR3 = B ;one full size ahead of input to place after


original pic in memory

nop
nop
nop
nop

B = AR5 ;increment current column

nop
nop
nop

B = B + #1

nop
nop
nop
nop

AR5 = B

aloop2 ;loop through each pixel


; *AR1, *AR1 + 1 are current pixels right now

;FIR code goes here


;A first input pixel

*******FIR CODE****************
;AR0, AR7 unused
;C(r, index) = macd([B(r,c) B(r,c+1)],h1);
;C(r, index+cols/2) = macd([B(r,c) B(r,c+1)],h2);
;index = index+1;
B = #0 ;n-pixels

nop
nop
nop
nop

AR7 = #2020h ;sets *AR7 to first of *AR1

nop
nop
nop

A = *AR1

nop
nop
nop
nop

*AR7+ = A

nop
nop
nop
nop

A = #0 ;sets A to AR1+32

nop
nop
nop

B = AR1

nop
nop
nop
nop

A = A+B

nop
nop
nop
nop

A = A+#32

nop
nop
nop
nop

AR0 = A

nop
nop
nop
nop

A = *AR0

nop
nop
nop
nop

*AR7+ = A

nop
nop
nop
nop

A = *AR7-

nop
nop
nop

A = *AR7-

nop
nop
nop
nop

B = #0

nop
nop
nop
nop

repeat(#ntaps - 1)
MACP(*AR7+, h2, B)

nop

B = B >> 10

nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop

;store into output - MEMORY ADDRESSING


;must store B to row which starts at AR3
;column of AR4
;memory location is going to be
;AR3+AR4*32
;have A, AR0, AR7

AR7 = B
A = AR3

nop
nop
nop
nop

B = AR4
AR0 = B

nop

B = B << 5

nop

A = A+B

nop

AR0 = A

nop

A = AR7

nop
nop
nop
nop

*AR0 = A

nop

A = AR4

nop

A = A + #1 ;increments index

nop

AR4 = A

A = AR1

nop

A = A + #64

nop

AR1 = A

*******************************

nop

;increment current pixel again (total by 2)

;B = *AR2-
if(*AR2- != 0) goto aloop2 ;if pixels remaining continue

*************************************************************

nop

if(*AR6- != 0) goto colp ;if columns remain continue


*********************END FIRST PART*****************

start2
AR5 = #0 ;AR5 holds current row (array indexing)
AR6 = #(nrows - 1) ;counter to loop through each row

rolp AR2 = #(halfn - 1) ;num times to loop in row (ncols?)


AR1 = #picbeg ;AR1 (input pointer) set to
beginning of pic
A = AR1
A = A+#size
AR1 = A

*******initialize the input/output pointers*****


B = AR5 ;init input ptr

nop

B = B << 5 ;find current row, mult by row length


A = AR1 ;(this setup specific to ncols = 32)

nop

B=B+A ;add to beg of pic to get


AR1 = B ;beginning of row

nop

B = B + #size ;setup output ptr


AR3 = B ;one full size ahead of input to place after
original pic in memory

nop

;situation:
;AR2 is 32
;AR6 is counter
;AR1 is beginning of current input row
;AR3 is beginning of current output row
;AR5 is row number for next row
;AR0, AR4, AR7 unused
********move down each column and compute h1/h2 filters******
AR4 = #0 ;index variable

nop

loop ;loop through each pixel


; *AR1, *AR1 + 1 are current pixels right now

;FIR code goes here


;A first input pixel

*******FIR CODE****************
;AR0, AR7 unused
;C(r, index) = macd([B(r,c) B(r,c+1)],h1);
;C(r, index+cols/2) = macd([B(r,c) B(r,c+1)],h2);
;index = index+1;

B = #0 ;n-pixels

nop

repeat(#ntaps - 1)
MACP(*AR1+, h0, B)

nop
nop

B = B >> 10

nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
;store into output - MEMORY ADDRESSING
;must store B to row which starts at AR3
;column of AR4
;memory location is going to be
;AR3+AR4
;have A, AR0, AR7

nop

AR7 = B
A = AR3

nop

B = AR4
A = A+B

nop

AR0 = A
A = AR7

nop

nop
nop
nop

*AR0 = A

nop

A = AR4
A = A + #1 ;increments index
AR4 = A

*******************************

nop

;increment current pixel again (total by 2)

;B = *AR2-
if(*AR2- != 0) goto loop ;if pixels remaining continue

*************************************************************

nop
AR2 = #(halfn - 1) ;num times to loop in row (ncols?)
AR1 = #picbeg ;AR1 (input pointer) set to beginning of
pic
A = AR1
A = A+#size
AR1 = A ;Add size to AR1 to set part 2s i/p to part
1s o/p

nop

B = AR5 ;init input ptr

nop

B = B << 5 ;find current row, mult by row length (32)

nop

A = AR1 ;(this setup specific to ncols = 32)

nop

B=B+A ;add to beg of pic to get


AR1 = B ;beginning of row

nop

B = B + #size ;setup output ptr


AR3 = B ;one full size ahead of input to place after
original pic in memory

nop

B = AR5 ;increment current row


B = B + #1

nop

AR5 = B

loop2 ;loop through each pixel


; *AR1, *AR1 + 1 are current pixels right now

;FIR code goes here


;A first input pixel
*******FIR CODE****************
;AR0, AR7 unused
;C(r, index) = macd([B(r,c) B(r,c+1)],h1);
;C(r, index+cols/2) = macd([B(r,c) B(r,c+1)],h2);
;index = index+1;

B = #0 ;n-pixels

nop

repeat(#ntaps - 1)
MACP(*AR1+, h2, B)

nop
nop

B = B >> 10

nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
;store into output - MEMORY ADDRESSING
;must store B to row which starts at AR3
;column of AR4
;memory location is going to be
;AR3+AR4
;have A, AR0, AR7

AR7 = B
A = AR3

nop

B = AR4
A = A+B

nop
AR0 = A
A = AR7

nop
nop
nop

*AR0 = A

nop

A = AR4
A = A + #1 ;increments index

nop

AR4 = A

*******************************

nop

;increment current pixel again (total by 2)

;B = *AR2-
if(*AR2- != 0) goto loop2 ;if pixels remaining continue

*************************************************************

nop

if(*AR6- != 0) goto rolp ;if rows remain continue

WAIT: nop
goto WAIT ; infinite loop at end of execution
.end
ee113filters.m:

function ee113filters()
function sum = macd(ar,h)
%incorporates repeat as well
sum = 0;
for i = 1:length(h)
sum = sum + h(i)*ar(i);
end

end

clear all;

[A,map] = imread('original.jpg','jpg');

B = double(A(:,:,1));

dim = length(B(1,:));

h1 = [0.707 0.707];
h2 = [-0.707 0.707];

A= B;
% the algorithm:

%A is image
%first step: perform B = Wn * A

%perform on each column in order:


% h1 filter
% h2 filter
% throw away every other result

for c = 1:dim;
%for each column

% h1 filter
index = 1;
for r = 1:2:dim;
%move down the column of A
B(index, c) = macd([A(r,c) A(r+1,c)],h1);
index = index+1;
end

% h2 filter
for r = 1:2:dim;
%move down the column of A
B(index, c) = macd([A(r,c) A(r+1,c)],h2);
index = index+1;
end

end

%second step: perform C = (Wn * B^T)

for r = 1:dim;
%for each row of B

% h2 filter
index = 1;
for c = 1:2:dim;
%move down the row of B
C(r, index) = macd([B(r,c) B(r,c+1)],h1);
index = index+1;
end

% h2 filter
for c = 1:2:dim;
%move down the row of B
C(r, index) = macd([B(r,c) B(r,c+1)],h2);
index = index+1;
end
end

%third step: perform T = transpose of C

out = C;

out2(:,:,1) = uint8(out);
out2(:,:,2) = uint8(out);
out2(:,:,3) = uint8(out);

imwrite(out2,'transformed_image.jpg','jpg');

end
output.m:

% EE 113D Final Project


% Herman Cheng, Zhicong Huang, Mark Kumimoto

% This program converts the raw data points from the DSP output into an
% image. It also outputs the image onto the computer.

close all;
clear all;
clc;

% VARIABLES
=============================================================
ORIGINAL = '32noword.asm'; % original image
RAW = 'dsp_output.dat'; % processed raw data points
OUTPUT = 'dsp_output.jpg'; % name of output file
%
=============================================================
==========

% Read data
=============================================================
==
original = load(ORIGINAL); % original image data with .word directives
removed
[row,col] = size(original);
raw1 = load(RAW); % raw data
%
=============================================================
==========

% Convert N^2 vector into NxN matrix


=============================================
raw1 = raw1'; % convert the column data into row data
filtered11 = []; % empty matrix ready for NxN image
for n = 1:row
filtered11(n,:) = raw1(col*(n-1)+1:col*n);
end

filtered1(:,:,1) = uint8(filtered11);
filtered1(:,:,2) = uint8(filtered11);
filtered1(:,:,3) = uint8(filtered11);
%
=============================================================
==========

imwrite(filtered1, OUTPUT, 'jpg'); % writes file to computer

dim = 32;
for r = 1:dim;
for c = 1:dim;
if (c == 2*r || c == 2*r - 1 )
Wn(r,c) = 0.707;
elseif c == 2*(r-dim/2)
Wn(r,c) = 0.707;
elseif c == 2*(r-dim/2)-1
Wn(r,c) = -0.707;
else
Wn(r,c) = 0;
end
end
end

original = inv(Wn)*filtered11*inv(Wn');
original2(:,:,1) = uint8(original);
original2(:,:,2) = uint8(original);
original2(:,:,3) = uint8(original);
imwrite(original2,'original_actual.jpg','jpg'); %Save the recovered image

% Plot data
=============================================================
===
figure(1);
subplot(3,3,2);
colormap('gray(256)');
imagesc(original);
title('Original Image');

subplot(3,3,5);
colormap('gray(256)');
imagesc(filtered1);
title('Image in Compressed Form');

subplot(3,3,8);
colormap('gray(256)');
imagesc(original2);
title('Recovered Image');
%
=============================================================
==========

% Clear data
=============================================================
==
clear ORIGINAL;
clear OUTPUT;
clear RAW;
clear raw1;
clear row;
clear col;
clear n;

You might also like