Introduction to Two Dimensional Arrays

Download and uncompress imageArrays.zip. Extract the files to your computer and open an Eclipse project yourLastName10a, then add these files to your project. Opened in BlueJ, the class relationships are clearly displayed below.

Run the program and the Image Viewer window will appear on your desktop.

Click on File Open, and select a jpeg of gif file to view. A couple of image files are provided in the compressed file to experiment with.

Click on Image Grey Scale 1 to see the first transformation. Right now, Transform 2 (Black and White), Transform 3 (Sobel Grey Scale), and Transform 4 (Sobel Outline) do the same transformation as Transform 1. You will be writing Transforms 2, 3, and 4.

Examine the ImageTransform code by clicking on the imageTransform.java icon in the Navigator View.

public Pixel[][] greyScale(ImageBuffer img) {
    Pixel[][] pix = img.getPixels();
    int height = pix.length;
    int width = pix[0].length;
    Pixel[][] buf = new Pixel[height][width];

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            Pixel p = pix[y][x];
            int gray = (p.getRed() + p.getGreen() + p.getBlue()) / 3;
            buf[y][x] = new Pixel(gray, gray, gray);
        }
    }
    return buf;
}

Answer the following questions in the body of your email -explore the source code and Java API as necessary.

  1. What data type is returned by greyScale? Do not merely name the object, but describe what type of data structure is being used.
  2. What is the name of the instance variable being returned in greyScale?
  3. How many times is the following code executed?
         Pixel p = pix[y][x];
         int gray = (p.getRed() + p.getGreen()
                   + p.getBlue()) / 3;
         buf[y][x] = new Pixel(gray, gray, gray); 
  4. What class will tell you what p.getRed() does?
  5. What other types of images does the program work on? You may need to download or create (open in Paint and use File-SaveAs) other types of images to answer this question.

Transform 2

Write the blackAndWhite method to convert a grey scale image to a black-and-white image. You can do this by applying a "threshold," where you color white any pixel whose brightness is above 127, and any other pixel you color black. You need only look at the red component of the pixel to determine its brightness; since it will be a grayscale image, the other color components will match it.

Note: Black is represented by the integer 0 and white is represented by 255.

Transform 3

Write the sobelGreyScale method to detect lines in a grayscale image. To do this, for each pixel you should do the following:

  1. First copy each pixel in the image to a Pixel double array named buf. Compute y (the vertical gradient) as the result of applying a convolution mask to the pixel, illustrated as follows:
    1 2 1
    0 0 0
    -1 -2 -1

    This mask represents that you should compute 1 times the brightness of the pixel just above and to the left of the current pixel, plus 2 times the brightness of the pixel just above the current pixel, plus 1 times the pixel just above and to the right of the current pixel, plus ...
    Corresponding maskY values are to be multiplied by the respective pixel and these nine values summed (note the second row does not contribute to the vertical gradient estimate so could be left off in this calculation.)

    Again, since this is grey scale, each color component of the pixels will be the same, and so you can get the brightness of a pixel by looking at its red component alone.
  2. Compute x (the horizontal gradient) as the result of applying the following mask to the pixel:
    1 0 -1
    2 0 -2
    1 0 -1

  3. Place into the resulting image (buf) a gray pixel whose brightness is the gradientEstimate = |x| + |y|.

This transform uses Sobel's edge detection (a pair of 3x3 convolution masks, one estimating the gradient in the x-direction (columns) and the other estimating the gradient in the y-direction (rows)), to answer the questions - Are this pixel's neighbors above different from its neighbors below? Are this pixel's neighbors to the left different from its neighbors to the right? If so, then set this pixel value to a value based on this dot product -the gradient estimate. Otherwise set this pixel value to the near zero or zero value of this dot product (black) that occurs when the neighbors have essentially the same intensity.
Check this website for more information on how this technique works: Edge Detection Tutorial

Transform 4

It is possible for the gradient estimate value,  |x| + |y|, to exceed 255 in red, green, or blue as our convolution mask weights the neighbors in both the horizontal and vertical by a factor of 4, we can scale the gradient estimate back to the range 0-255 by dividing by 8. For the sake of seeing just the outline we can change only the edge detected pixels leaving the original (grey scale) pixels untouched. Write the sobelOutline method to further enhance the performance seen in sobelGreyScale by first replacing the pixel only if the gradientEstimate, (|x| + |y|) / 8, exceeds a threshold value (you determine what threshold value works best). Replace the pixel with a single color pixel (pick your favorite color from red, green, or blue).

 


Based on the lab materials by Kathleen Weaver, Jack Tompkins, UNCW.