Assembly
Computer Organization and Assembly Languages, Fall 2006

Jump to...

assignment #1
assignment #2
assignment #3
assignment #5
final project
assignments


Assignment #4: Box Filter

Assigned: 11/27/2006
Due: 12/13/2006 11:59pm (extended)

Description

Smoothing filters are useful image processing tools for blurring and for noise reduction. They use spatial coherence and pixel value homogeneity of a pixel's neighborhood as bases. Noise-cleaning techniques detect lack of coherence and either replace the incoherent pixel value by something more spatially coherent by using some or all of the pixels in a neighborhood containing the given pixel or smooth the pixel value with others in an appropriate neighborhood. The operator that computes the equally weighted average is called the box filter operator.

Given an image f, the box filter operator with a (2M+1)X(2N+1) smoothing neighborhood is defined by

where k(r, c) represents the pixel value of the filtered image k at the r-th row and the c-th column. Although directly implementing the above function produces the correct filtering result, this naïve method is very slow. Since such image-processing techniques usually have to meet the timing constraint for interactive playing, please try to come up with some ways to improve the speed. One effective way to speed up box filter is to use the summed area table method.

Specification

You have to implement a procedure called blur using assembly. This function should accept a pointer pointing to the image data, a pointer pointing to the output destination, the size of the kernel, the width of the image, and the height of the image. The filtering result should have been written back to the memory when this function returns. A skeleton code looks like:
    .386
    .model flat
    option casemap :none

    ; tell assembler these are external C procedures.
    EXTERN C malloc: proc
    EXTERN C free: proc

    .data
        tmp DWORD 0
    .code
    _blur PROC PUBLIC
        push ebp
        mov ebp, esp ; build stack frame

        ; variables in stack
        ; [ebp+24]  image height (the 5th argument)
        ; [ebp+20]  image width  (the 4th argument)
        ; [ebp+16]  kernel size  (the 3rd argument)
        ; [ebp+12]  pointer to the output image (the 2nd argument)
        ; [ebp+8]   pointer to the input image  (the 1st argument)
        ; [ebp+4}   return address
        ; [ebp]     previous ebp

        ; begin blurring operation
        ; WRITE YOUR OWN CODE HERE

        ; end blurring operation

        leave
        ret
    _blur ENDP
    END ; file ends here
In hw4.zip, you can find the files you might need and main.c where other functions are implemented. They are used to process the image-I/O tasks (24-bit BMP only) and do timings, and you don't need to modify them. To simplify your task, the main procedure actually read in a 24-bit BMP, convert it to a grey image and pass the grey image to your procedure. Hence, you should assume that you are working on a grey-level image. We have provided a MSVC++ 2005 project file so that you can build the executable file once you have finished your blur function. Execute "blur.exe INPUT_FILENAME OUTPUT_FILENAME" and you will have the filtered image named OUTPUT_FILENAME and CPU cycles you've used.

A function called c_blur() in main.c is a C implementation of the box filter. You can use it to verify your result. To verify your result, you can compare the CRC32 or MD5 checksums of the filtering results generated by c_blur and your own procedure. To avoid collision, we will use MD5 checksum to check your results. You can find a MD5 calculator at http://www.fourmilab.ch/md5/ (a copy of md5.exe is attached in hw4.zip). For example, the MD5 checksum of the "sample1_out.bmp" in hw4.zip is AF6A54367FE4F0DAC5FBA9F562F38DB0.

If you would like to speed up your blur function by implementing the summed area table method introduced in the class, you need to allocate a piece of memory space for the sum-area table. One option would be to allocate space in the stack area. However, the default stack size for Windows is small (only 1MB). Thus, we would suggest you to use malloc to allocate memory. Before calling malloc, you need to inform the assembler that malloc is an external C function by adding the following code fragment,
    EXTERN C malloc: proc
We have done this for you in the skeleton code. So, you can just use malloc if you wish. For example, to allocate a 4MB memory space, you can add the following code fragment,
    mov ebx, 1048576 * 4
    push ebx
    call malloc
    add esp, 4
    ; eax is now a pointer to malloc-ed memory
No that, in the above code, the last statement is used to "clean up" the stack you used for passing argument. If you don't, it could lead to errors. To free the space you have allocated, you can cll free as the following,
    push eax	; eax the the pointer returned by malloc
    call free
    add esp, 4

Grading

As the previous assignment, you will get 80 points if you implement this procedure correctly. Another 0~20 points will be added to your grade depends on the speed of your program and 0~10 points depends on the code size.

Submission

Submit your homework through online submission system.