Вы находитесь на странице: 1из 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 T = WN AWN

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 2 0 0 0 H WN = = G 1 2 0 0 0 1 2 0 0 0 1 2 0 0 0 0 1 2 0 0 0 1 2 0 0 0 1 2 0 0 0 1 2 0 0 0 0 1 2 0 0 0 1 2 0 0 0 1 2 0 0 0 1 2 0 0 0 0 1 2 0 0 0 1 2 0 0 0 1 2 0 0 0 1 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 = W N1TWN 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 column of image with downsampling Second column, third column, etc Delay 0 Delay 2 Delay 4 Delay 0 Delay 2 Delay 4

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

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 Hex Grayscale Values
A

1800

1C00

Intermediate Result B Hex Grayscale Values

B = WN A

2000

Transformed Image T Hex Grayscale Values

T T = BWN

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 T = WN AWN

The inverse transformation using the matrix equation,


A = WN1TWN 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 1316, 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 data stored in first block .setsect ".text", 0x0180, 0 .setsect "coeff", 0x07F8, 0 .setsect "pic" , 0x1800, 0 program memory .setsect "OPpic", 0x1C00, 0 .sect "pic" picbeg .copy "32.asm" values .sect "OPpic" pic2 .sect "coeff" .copy "8tap.asm" ;label for output picture ; 2-tap wavelet FIR ;original pic, loaded as array of 8bit luminance ;all program code, FIR coeffs and temp ;of program memory ;pictures will be stored in second block of

; coefficient values here .data ; data section where ; intermediate results of the ; calculations will be stored ; ; extra word for the bit bucket

XN .word 0,0,0,0,0,0,0 XNLAST .word 0 OUTPUT .word 0 .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 AR6 = #(ncols - 1) new: ;DP = #XNLAST ;data ptr to allow buffer access ;AR5 holds current column (array indexing) ;counter to loop through each row

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

colp pic

AR2 = #(halfn - 1) AR1 = #picbeg

;num times to loop in col (nrows?) ;AR1 (input pointer) set to beginning of

*******initialize the input/output pointers***** B = AR5 ;init input ptr

nop nop nop nop A = AR1 nop nop nop nop B=B+A AR1 = B nop nop nop nop B = B + #size AR3 = B 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 ;setup output ptr ;one full size ahead of input to place after ;add to beg of pic to get ;beginning of column ;(this setup specific to ncols = 32)

;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 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 ;n-pixels

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 = *AR7nop nop nop nop A = *AR7nop 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 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 ******************************* ;increments index

nop nop nop nop ;increment current pixel again (total by 2) if(*AR2- != 0) goto aloop ;B = *AR2;if pixels remaining continue

************************************************************* nop nop nop nop AR2 = #(halfn - 1) AR1 = #picbeg pic nop nop nop nop ;num times to loop in row (ncols?) ;AR1 (input pointer) set to beginning of

B = AR5 nop nop nop nop nop A = AR1 nop nop nop nop B=B+A nop nop nop

;init input ptr

;(this setup specific to ncols = 32)

;add to beg of pic to get

AR1 = B nop nop nop nop B = B + #size nop nop nop AR3 = B original pic in memory nop nop nop nop B = AR5 nop nop nop B = B + #1 nop nop nop nop AR5 = B aloop2

;beginning of row

;setup output ptr

;one full size ahead of input to place after

;increment current column

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

;n-pixels

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 = *AR7nop nop nop A = *AR7nop 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 nop AR4 = A A = AR1 nop A = A + #64 nop AR1 = A ******************************* nop ;increment current pixel again (total by 2) if(*AR2- != 0) goto aloop2 ;B = *AR2;if pixels remaining continue ;increments index

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

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

rolp

AR2 = #(halfn - 1) AR1 = #picbeg beginning of pic A = AR1 A = A+#size AR1 = A

;num times to loop in row (ncols?) ;AR1 (input pointer) set to

*******initialize the input/output pointers***** B = AR5 ;init input ptr nop B = B << 5 A = AR1 nop B=B+A AR1 = B nop B = B + #size AR3 = B 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 ;setup output ptr ;one full size ahead of input to place after ;add to beg of pic to get ;beginning of row ;find current row, mult by row length ;(this setup specific to ncols = 32)

********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 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 ;n-pixels

;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 AR4 = A

;increments index

******************************* nop

;increment current pixel again (total by 2) if(*AR2- != 0) goto loop ;B = *AR2;if pixels remaining continue

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

AR1 = #picbeg pic A = AR1 A = A+#size AR1 = A 1s o/p nop B = AR5 nop B = B << 5 nop A = AR1 nop B=B+A AR1 = B nop B = B + #size AR3 = B original pic in memory nop B = AR5 B = B + #1 nop AR5 = B loop2

;AR1 (input pointer) set to beginning of

;Add size to AR1 to set part 2s i/p to part

;init input ptr

;find current row, mult by row length (32)

;(this setup specific to ncols = 32)

;add to beg of pic to get ;beginning of row

;setup output ptr ;one full size ahead of input to place after

;increment current row

;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 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 ;n-pixels

AR0 = A A = AR7 nop nop nop *AR0 = A

nop

A = AR4 A = A + #1 nop AR4 = A

;increments index

******************************* nop ;increment current pixel again (total by 2) if(*AR2- != 0) goto loop2 ;B = *AR2;if pixels remaining continue

************************************************************* nop if(*AR6- != 0) goto rolp WAIT: nop goto WAIT .end ;if rows remain continue

; infinite loop at end of execution

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'); dim = 32; for r = 1:dim; for c = 1:dim; % writes file to computer

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;

Вам также может понравиться