LAB 18 – Conditionally Modifying Pixels (part 2 – Simple Edge Detection)

Topics

n      To do simple edge detection.

n      To replace several colors in a picture: sepia-toned.

n      To use a conditional with two possible results if and else.

 

6.1 Conditional Pixel Changes

Type in the following code in the Program window (changing the comments):

 

import java.awt.Color;

/* Program that transforms pictures using loops and conditionals

 *

* Picture and Pixel classes are defined in bookClasses developed

 * at Georgia Tech by Mark Guzdial / Barbara Ericson

 *

 * @author Wayne Summers

 * @date   Sept. 23, 2007

 */

 

public class TransformPictures

{

  public static void main(String[] args)

  {

    String fileName1, fileName2;

    System.out.println(“Find the source file”);

    fileName1 = FileChooser.pickAFile();  // note that this pops up a window to select a jpg file

    Picture sourcePicture;

    sourcePicture = new Picture(fileName1);

 

// calls to methods that manipulate images go here

 

   sourcePicture.show(); 

  }

}

 

6.2 Simple Edge Detection: Conditionals with Two Options

i) Type in the following code in the Program window below the main method and before the last }:

 

/**

  * Method that does simple edge detection by comparing the absolue value of the difference between the color

  * intensities between a pixel and the pixel below it. If the absolute value of the difference is less than

  * the passed value, the top pixel color will be set to white, otherwise it will set to black

  * @param sourcePic - picture Object to be modified

  * @param distance – distance allowed between adjacent pixels

*/

  public static void edgeDetection (Picture sourcePic, double distance)

  {

     Pixel topPixel = null;

     Pixel bottomPixel = null;

     double topAverage = 0.0;

     double bottomAverage = 0.0;

     int width = sourcePic.getWidth();

     int height = sourcePic.getHeight();

   

    // loop through the y values from 0 to (height-1) since we compare to pixel below

    for (int y = 0; y < (height-1); y++) 

    {

        // loop through the x values from 0 to width

        for (int x = 0; x < width; x++)

        {

            // get the top and bottom pixels

            topPixel = sourcePic.getPixel(x,y);

            bottomPixel = sourcePic.getPixel(x,y+1);

           

            // compute the color averages for the two pixels

            topAverage = topPixel.getAverage();

            bottomAverage = bottomPixel.getAverage();

 

          // check if absolute value of the difference is less than distance

            if (Math.abs(topAverage - bottomAverage) < distance)

                topPixel.setColor(Color.WHITE);

            else

                topPixel.setColor(Color.BLACK);

         } //end inner loop

    } //end outer loop

  }

 

ii) Type in the following code in the Program window in the main method and before the pic.show();

 

edgeDetection (sourcePicture, 10);

 

iii) Test your program with different pictures and values for the distance (e.g. butterfly1.jpg, 10).

 

EXTRA (if there is time)

6. 3 Sepia-tinted and Posterized Pictures: Using Multiple Conditionals to Choose a Color

iv) Type in the following code in the Program window below the main method and before the last }:

 

  /**

  * Method to convert sourcePic to a sepia tint (modify the middle colors to a light brown

  * and the light colors to a light yellow and make the shadows darker

  * @param sourcePic - picture Object to be modified

*/

  public static void sepiaTint(Picture sourcePic)

  {

    Pixel pixelObj = null;

    double redValue = 0;

    double greenValue = 0;

    double blueValue = 0;

    int width = sourcePic.getWidth();

    int height = sourcePic.getHeight();

 

 

    // first change the current picture to grayscale

    grayscale(sourcePic);

 

    // loop through the pixels

    for (int x = 0; x < width; x++)

    {

      for (int y = 0; y < height; y++)

      {

        // get the current pixel and color values

        pixelObj = sourcePic.getPixel(x,y);

        redValue = pixelObj.getRed();

        greenValue = pixelObj.getGreen();

        blueValue = pixelObj.getBlue();

        // tint the shadows darker

        if (redValue < 60)

        {

          redValue = redValue * 0.9;

          greenValue = greenValue * 0.9;

          blueValue = blueValue * 0.9;

        }

        // tint the midtones a light brown by reducing the blue

        else if (redValue < 190)

        {

          blueValue = blueValue * 0.8;

        }

        // tint the highlights a light yellow by reducing the blue

        else

        {

          blueValue = blueValue * 0.9;

        }

 

        // set the colors

        pixelObj.setRed((int) redValue);

        pixelObj.setGreen((int) greenValue);

        pixelObj.setBlue((int) blueValue);

      }

    }

  }

 

v) Type in the following code in the Program window in the main method and before the pic.show();

 

    sepiaTint(sourcePicture);   and test with the picture gorge.jpg [DON’T FORGET TO INCLUDE the grayscale method from LAB 12.

 

vi) Test your program with other values multiplying blueValue.

 

 

 

QUESTIONS:

Modify the edgeDetection method to allow for changing just part of the picture by passing in the startX, startY, endX, and endY values (see the replaceColor method from lab17)

 

Submit the .java file (with edgeDetection where you set the arguments in the main method to values that will allow you to select a region of the picture to change) through the DropBox in WebCT.