Lab: Local Operators

CSC 295 - Computer Vision - Weinman



Summary:
We explore local pixel operations including gamma, bias, and gain adjustments along with the more interesting histogram equalization.
Due:
Monday 2/08

Deliverables

Note: You may wish to include several images in one figure box (i.e., the gamma, bias, and gain adjusted images) for both compactness and ease of comparision. For example, see Figure 3.1 (p. 102) of Szeliski.

Extra

Preparation

Exercises

A. Pixel Transforms

While this first portion of the lab will call on you to make some observations, you should try not to spend too much time on them just now. You will want to make sure you have plenty of class time to work through the remaining technical material. Once you have all the technical aspects done, you can further explore values and their effects and reflect on the results for your analysis.
  1. Matlab has a default search path for some demo images. One of these is the cameraman.tif. Load this image using imread.
  2. The image is currently in an 8-bit format (values 0-255), which we'll need for later. However, we'll also need a double version. Create a copy that has double values in 0-1. (You learned how to do this in the Matlab exercises.)
  3. Create a version of this image (using the double representation) that uses the gamma correction suggested by Equation (3.7) in Szeliski and his suggested value for gamma, 2.2.
    Recall that you must prepend a "." to explictly vectorize an operator (such as exponentiation) so that you don't get a matrix operator (such as matrix exponentiation). For instance A*B will multiply matrices A and B if it is appropriate to do so, while A.*B will multiply the corresponding entries in A and B.)
  4. Display, inspect, and save this image. What differences do you notice, if any?
  5. Equation (3.3) in Szeliski suggests a contrast and brightness adjustment via a linear transformation. Create a version of the cameraman image with a bias adjustment to noticeably increase the brightness.
  6. Display, inspect, and save this image. What (non-obvious) differences do you notice, if any? (E.g., don't just say "the image is brighter")
  7. Create a version of the cameraman image with a gain adjustment to noticeably increase the contrast.
  8. Display, inspect, and save this image. What non-obvious differences do you notice, if any?

B. Computing Histograms

  1. Matlab has a built-in function for helping to visualize histograms of images called imhist. Use this to display a histogram of the original (8-bit) cameraman image.
  2. More often we will be creating histograms of quantities besides raw images, so it is useful to know about the more general hist function for creating histograms. Use this to display a histogram of the image. For example,
    hist(X(:));
    Note that hist requires a vector, which we can convert our image to using the (:) indexing notation. Also, some versions of Matlab don't like to use uint8 variables in hist, so you may need to convert the vector to a double, but keeping the values in the 0-255 range, as in
    hist(double(X(:)));
  3. How many bins are used? Where (roughly) are they located?
  4. If you pass a second vector argument to hist, it will use the values in the vector as the histogram bin centers. Since the 8-bit image contains numbers 0-255, it is natural to use these as our bin centers. Create a histogram with the integers 0-255 as the bin locations. This should look similar to the histogram created in 1, except it does not show you the brightness along the bottom, only the brightness value (e.g numbers), since the result is a simple bar chart.
  5. What if you want to save these values (counts, actually) for processing? You can assign the result to a variable
    Xhist = hist(...
    Save the histogram using 0-255 as the bins in a variable.
  6. The command bar(X,Y) graphs a bar chart of the values in the vector Y at the locations in the vector X (in the usual x vs. y fashion). Use this to generate your own graph of the histogram you just saved.
  7. Use xlabel and ylabel to give appropriate titles to the axes and save this plot using the print command you learned in the previous lab.
  8. What brightness levels in the histogram appear to have the most pixels? Where do you expect to see the most detail emerge from the equalization enhancement?

C. Image Mapping

While adjusting the gain of an image increases the contrast, it may not necessarily allow us to see the most detail present in an image. Spreading out the brightness values so that they are used uniformly is often a useful of way doing this. First, we need to figure out how to "map" one brightness value to another.
  1. Use the following commands to create a faint image of a square with a hole in it.
    S = zeros(128,'uint8');  % Black background
    S(32:96,32:96) = 2;      % Square
    S(48:80,48:80) = 1;      % Hole 
  2. Use imshow to display the image. It should be hard, if not impossible to see the three levels since they are all very close (0,1 and 2 on a 0-256 scale).
  3. These pixel values can be used as indices into another array. Use the following to create the 3-element brightness map
    map = uint8([0 128 255]);
    Notice how we have explicitly made these values 8-bit. This will be so that imshow interprets them correctly.
  4. Recall that nearly anything can be used as an index to an array, even another vector or a matrix. Thus, we can use S as the index into the array map. What will be the result of the following expression?
    S2 = map(S);
    Verify your answer.
  5. There is one caveat: the values in S are 0, 1, and 2, while the valid indices of map should be 1, 2, and 3. Thus, we would need to add 1 to S in order to index properly (that is, without getting an error). What should the following produce?
    S2 = map(double(S)+1);
    Display the result. Does it look as you appear? Note that we need to cast S to a double (which is different from converting an image using im2double) so that values don't get clipped at 255.
  6. Experiment with a different set of values for map and construct a new image. Make sure you understand what is happening before proceeding.

D. Histogram Equalization

Figure 3.7(b) in Szeliski (p. 111) displays the histogram of each color channel. The plot in (c) contains the cumulative distribution function, which is just the sum of all the values to the left of each point in the histogram. Thus, you see the blue curve ramp up very quickly because there are many values in the histogram to the left. As we move right (increasing in brightness) there are very few entries in the histogram. The cumulative distribution function thus increases slowly because there is not very much to add. Our end goal is to use this function to transform the histogram so that it is flat (given a cumulative distribution function that is a straight line ramp).
  1. You can calculate the cumulative sum of the elements in a vector (as described above) using the function cumsum. Use this to create the cumulative distribution function from your histogram counts.
  2. Plot the cumulative distribution function using the plot(X,Y) command. (Don't forget to specify the correct x-coordinates.)
  3. Save this plot using the print command. (Don't forget to label your axes!)
  4. Next, we need to transform the cumulative distribution function into a proper mapping. That is, the entries should be brightness values in the range 0-255. What is the smallest value in your cumulative distribution function? What is the largest value?
  5. Create a scaled version of your cumulative distribution function so that the smallest value is zero but the largest value is 255 (the maximum brightness).
  6. Your scaled cumulative distribution function is likely a double (confirm this). Since we want to use this scaled version as a map like we did in Part C, we will need to cast these values using uint8. Do this to your new map.
  7. With the same technique you learned in part C, use the original (8-bit) image as an index into your map (the scaled, 8-bit cumulative distribution function). The result should be an image that has undergone histogram equalization.
  8. Display, inspect, and save your image. What new things do you notice, if any?
  9. Display, inspect, and save the histogram of your new image. Does it have the properties you expect?

Extra Credit: Blending Maps

  1. Szeliski suggests that the result can be "flat" or "muddy" and suggests creating a linear blend between the cumulative distribution function and the identity transform (a straight line). Create a map that is the identity transform.
  2. Create a new transform function (map) that is the weighted average of your original map and your identity map (say, with an alpha of 0.75).
  3. Plot the original map and your blended map on the same axes (use hold on between plot commands). The following example demonstrates one way to change the color and line style of a plot
    plot(X,Y,'k--');
    In this case, the last argument indicates to use a black dashed line. You may examine other options by reading the help for the plot command.
  4. Save your plot. How do the two maps compare?
  5. Display, inspect, and save the image using this blended map. How does it compare to the first equalized image? The original image?

Copyright © 2010 Jerod Weinman.
ccbyncsa.png
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.