Spring 2004 - CS477/577 - An Introduction to Computer Vision

Assignment Four

Due: Tuesday, March 23, 2004 (4:00 AM on Mar 24 for night owls).

Credit (U-grad): Approximately 6 points (Relative, and very rough absolute weighting)
Credit (Grad): Approximately 5 points (Relative, and very rough absolute weighting)

This assignment is meant to help you get familiar with some useful tools and ideas. It is not meant to be mathematically or technically difficult. If you are having trouble, please see Scott rather than beat your head against a wall. (Expend your creative energy on the project instead).

You can do this assignment in either Matlab or C/C++ using whatever libraries you like.

For those wanting to use the KJB libray, I have tweaked it a bit for this assigment. Recall that there is an example program and a compile line available in this directory . There are hopefully enough comments in example.c to get you started. The file compile_line deals with the complexities of including and linking. (Those that are using the library more seriously in the long run should, at some point, talk to me regarding a more sophisticated way to use the library which is necessary if you want to modify it). The files matrix.txt and image.tiff can be used as data for the example program.

If you are using the KJB library, the following routines might prove useful (man pages should be available, although the quality may not be high!):

    kjb_read_image
    kjb_write_image
    kjb_display_image

    ow_make_black_and_white_image
    bw_image_to_matrix
    matrix_to_bw_image

    get_1D_gaussian_mask
    get_2D_gaussian_mask

    x_convolve_matrix
    y_convolve_matrix
    convolve_matrix
Matlab users: Some functions which may prove helpful are:
    conv2 
To keep things simple, we will focuss on black and white (gray level) images. This means that an image is basically a matrix. Thus both in Matlab and in C it likely easiest to get the image into a matrix, work on the matrix, and then convert the matrix back to an image for IO.

An example BW image is here.

In case the word "roughly the same" confuses you in what follows: In several cases there are some subleties in implementing the various strategies for calculating the same quantity multiple ways, so just because they are mathemetically the same, checking that things are working may not require that you get exactly the same answer. What to hand in: : Your source code, and executable (if C), a README answering the few questions asked as well as any other comments about your work which are relevent, and the result images requested for one input image. If your input image is not the one pointed to above, also provide your input image. It is quite instructive to run your code on a number of different kinds of images, but this is not required.


  1. Write a program to show the magnitude of the gradient of an input image ("input.tiff"), using convolution to implement finite differences. You will want to scale your result so that it looks resaonable. Output this as 1.jpeg.

  2. Now find a threshold for the gradient magnitude to determine real edges. Make a new image which is white if the gradient magniture exceeds that threshold, and zero otherwise. Likely you will find that setting a threshold to identify exactly all points on what you would like to call significant edges is difficult or impossible. If this is not the case, then the image you are using is likely too easy! Don't spend too much time tweaking the threshold, but do find a reasonable value. Output this as 2.jpeg.

  3. Now use convolution to smooth the image with a Guassian mask with sigma set at 2 pixels. In preparation for (6), use a convolution routine which does not assume anything about the mask (i.e., you could change the Gausian to something else, and the code would be correct). Output this as 3.jpeg.

  4. Apply the procedure from (1) and (2) to the blurred image computed in (3). Thus for the resulting image from (3) do edge detection as in (1) and (2) and find a threshold for declaring an edge, and output a binary image based on that threshold. Output this as 4.jpeg.

  5. Now convolve the image with an appropriate single mask to implement smoothing by 4 pixels composed with doing the finite difference in one direction. Do the same for the other direction, and output the new gradient images as 5.jpeg. Verify for yourself that this gives roughly the same result as doing (3) then (1) above with the new same sigma.

  6. A function is said to be separable (in x and y), if f(x,y)=g(x)h(y), If this is the case, then convolution with f(x,y) can be implemented as a 1D convolution by g(x) followed by a 1D convolution by h(y). Reimplement the smoothing in (3) using this approach. Verify for yourself that this gives rougly the same result as before.

    Do you expect any speed difference? Why? Do you see any speed difference? (You may want to put the convolution in a loop, or use a bigger sigma and image to test for time differences).

    Matlab users: This is just a matter of calling conv2 with different parameters.
    KJB library users: See x_convolve_matrix and y_convolve_matrix.

To hand in the above, use the turnin program available on lectura (turnin key is cs477_hw4).