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

Assignment Two

Due: Tuesday, February 5, 2008, Midnight

Credit: Approximately 4 points (Relative, and very rough absolute weighting)

This assignment must be done individually


You can do this assignment in either Matlab or C/C++.

It is probably a bit easier in Matlab, but doing some of the assignments in C may prove to be a useful exercise. If you think that vision research or programming may be in your future, you might want to consider doing some of the assignments in C/C++. If you are stretched for time, and like Matlab, you may want to stick to Matlab. Your choice!

Information for those working in C/C++.


Assignment specification

This assignment has three parts. The second part is only required for grad students.

To simplify things, you should hard code the file names in the version of your program that you give to the TA.

Part A

The file
    /cs/www/classes/cs477/spring08/ua_cs_only/assignments/rgb_sensors.txt 
is an ASCII file containing a 101 by 3 matrix representing estimates for the spectral sensitivities of a camera that the instructor uses for his PHD work. There are 101 rows because the spectrophotometer used to determine them samples light at wavelengths from 380 to 780 nanometers in steps of 4 nanometers, inclusively.

For this assignment you need to write a program which does the following.

  1. Generate 2000 random light spectra. The standard random number generator is fine. (The spectra need to be positive). They each need to have 101 elements.
  2. Compute the (R,G,B) responses for the 2000 light spectra.

    Scale is arbitrary in this assignment. Real light spectra measured by our spectrophotometer that gives sensor responses in the range of (0,255) have power per wavelength of the order of 1e-4, not of the order of 1.0 as given by rand().

    Determine a scale factor, K, that scales (multiplies) your 2000 (R,G,B) so that the maximum of any of the (R,G,B) is 255. (You do not need to report this value).

    Multiply the randomly generated light spectra by K, and regenerate the (R,G,B). Verify that the max R,G,or B is now 255.

  3. Now simulate measurement error by adding random noise to the (R,G,B). Start with noise of the order 10. Since you scaled the data to (0,255), this is about 2.5%.

    (More specifically, generate random numbers in [-10,10] and add them to your (R,G,B).

  4. You now have a simulation of a camera calibration experiment. You have light spectra, and you have a bunch of responses. Use the least square method developed in class to estimate the camera sensitivities.
  5. Plot the "real" sensors and the estimated ones on the same plot. This is the only real deliverable. The TA will run your program and look at the plot. She may peak at the code, but likely will not probe deeply if the plot is reasonable.

Part B (only required for grad students).

Simulation is not reality. The file
    /cs/www/classes/cs477/spring08/ua_cs_only/assignments/light_spectra.txt
is a file of 598 real light energy spectra. Note that wavelength is now across columns (opposite to rgb_sensors.txt). The file
    /cs/www/classes/cs477/spring08/ua_cs_only/assignments/responses.txt 
are corresponding real (R,G,B).
  1. Estimate the camera sensitivities using this data. Again, the deliverable is a plot with both the real sensors and the estimated ones that will appear when the TA runs the code.
  2. Hopefully you will find that your sensors are terrible! Can you explain this (in the README)? Consider that the real light spectra came from a limited number of sources, through a limited number of filters, hitting a limited number of surfaces. Further, the reflectance spectra of most surfaces is smooth, which implies that they have limited dimension. For example, you can reconstruct them from a small set of sines and cosines (Fourier series).
  3. We can make things better by doing constrained least squares. For example we can insist that the solution vector is positive. Implement this. If you are doing this in Matlab, you will need to use a function like quadprog. (The way quadprog() is set up is a little different than what you might expect. Here is a link to a simple example if you are having trouble. If you are using the UA vision library (KJB library), then you will want to look at the man page for constrained_least_squares(). Again, plot the results.
  4. Hopefully you will now have positive sensors, but they are still weird. The problem is that they are not smooth. We can promote a smooth fit as follows. First, construct a matrix which can be used to multiply a spectra vector, and returns a second vector which is the successive differences of the elements of the input spectral. The matrix implements a simple derivative estimate. Ignore fence post error (i.e. you can compute 100 differences for a 101 element spectra). Hence, if M is the matrix, and R is a sensitivy response function (e.g. for the red channel), then D=M*R is a vector of 100 elements, where
            D    =    R      - R 
             i         i+1      i
    

    Further, introduce a scalar multiple of the above differencing matrix which we will refer to as lambda. You will tweak lambda below.

    We want a smooth function, so we want the differences to be small. In least squares, this means that we want them to be (approximately) zero. Augment your light_spectra matrix with another 100 rows that is the differencing matrix. Augment your response (R,G,B) matrix to have the desired result (zero).

    Verify for yourself that tweaking lambda adjusts the balance of fit and smoothness. You should be able to produce very smooth curves that do not resemble sensors, and curves approaching the ones in the previous part (of course, lambda == 0 should be exactly the same sensors as before).

    Note: Lambda implements the desired effect because in least squares any row can be weighted by simply multiplying both the row and the response by a scalar. (If the scalar were 2, this is exactly equivalent to duplicating the row.)

    Tweak lambda to give reasonable curves. Note that the curve for blue (leftmost, covering the smaller wavelengths) cannot be fit very well. Don't worry about this.

Part C (optional in 2008, not graded)

This is similar to a part of a graphics assignment that some of you have done (hence it is not fair to grade it in 2008).

Below are links to two images. Dump these into a into a drawing program, and draw enough lines over the image to make a case that the image is either approximately in perspective or not. (Have a look at the building examples in the lecture notes if this is not making sense). You should understand and state your assumptions. To get you started: You can assume that that the chandelier is perfectly symmetric.

Your deliverables for this part of the assignment should be the PDFs of your image with lines drawn on them and an explanation of what you conclude.

Image one

Image two


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

You should provide either a Matlab program or a C/C++ program that makes plots as described above. If you are working in C/C++, you should also provide source code and a Makefile. Grad students should try to answer the question regarding the cause of the messy pseudoinverse fit. Finally, you need a answer for question C in PDF.