CS585 Homework Assignment 1: Face\ImageFunct.java
  1 /*
  2  * ImageFunct.java
  3  *
  4  * ImageFunct - this class defines STATIC methods used to manipulate and handle 
  5  * images and pixels within the motionDetection and Face Detection problem.
  6  *
  7  * @author Benjamin Ring
  8  * Created on September 16, 2005, 4:30 PM
  9  * Updated on January 30, 2006
 10  */
 11 
 12 import javax.swing.*;
 13 import java.awt.Image;
 14 import java.awt.image.*;
 15 import java.awt.*;
 16 
 17 public class ImageFunct {
 18     
 19    //  toBufferedImage -- accepts an image and returns a copy of the image in 
 20    //       the form of a "bufferedImage"
 21    //
 22    //       REFERENCE: Patrick Chan, "The Java Developer"s Almanac 1.4"
 23    //
 24    public static BufferedImage toBufferedImage(Image image) {
 25         if (image instanceof BufferedImage) {
 26             return (BufferedImage)image;
 27         }
 28         image = new ImageIcon(image).getImage();
 29         BufferedImage bimage = null;
 30         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
 31         try {
 32             int transparency = Transparency.OPAQUE;
 33             GraphicsDevice gs = ge.getDefaultScreenDevice();
 34             GraphicsConfiguration gc = gs.getDefaultConfiguration();
 35             bimage = gc.createCompatibleImage(image.getWidth(null), 
 36                                         image.getHeight(null), transparency);
 37         } catch (HeadlessException e) {
 38             // The system does not have a screen
 39         }
 40         if (bimage == null) {
 41             int type = BufferedImage.TYPE_INT_RGB;
 42             bimage = new BufferedImage(image.getWidth(null), 
 43                                         image.getHeight(null), type);
 44         }
 45         // Copy image to buffered image
 46         Graphics g = bimage.createGraphics();
 47         // Paint the image onto the buffered image
 48         g.drawImage(image, 0, 0, null);
 49         g.dispose();
 50         return bimage;
 51     } 
 52 
 53    
 54    //  findFace -- Identify all "flesh colored" pixels in an image
 55    //
 56    //       GIVEN: A BufferedImage
 57    //       EFFECT: Pass once through the entire image; For each pixel, invoke
 58    //                           the "isFlesh" function to conduct a simple color comparison
 59    //                           in order to determine if the given pixel is "flesh colored."
 60    //                           If it is, copy it to the new image; otherwise paint a black
 61    //                           pixel in its place.
 62    //           RETURN: Returns a black background image with the flesh colored pixels 
 63    //                           copied from the original
 64    public static BufferedImage findFace (BufferedImage img)  {
 65            BufferedImage temp = new BufferedImage (img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
 66            for (int x = 0; x < img.getWidth(); x++)  {
 67                    for (int y = 0; y < img.getHeight(); y++)  {
 68                            Color pixel = new Color(img.getRGB(x, y));
 69                            if (isFlesh(pixel))
 70                                    temp.setRGB(x, y, pixel.getRGB());
 71                            else
 72                                    temp.setRGB(x, y, Color.BLACK.getRGB());
 73                    }
 74            }
 75            return temp;
 76    }
 77    
 78 
 79 
 80    //  isFlesh -- determine if a pixel is a "flesh colored" one
 81    //
 82    //       GIVEN: A 24-bit Color Object
 83    //       EFFECT: 
 84    //                   1. First, the procedure filters out all colors whose red & green components
 85    //                           fail to fall above a certain thershold (Color value of 50); 
 86    //                   2. Second, By plotting the Red & Green components of the Color Object as a vector
 87    //                           and subsequently comparing that Vector with two known Skin Tone Vectors,
 88    //                           denoted as Skin1 & Skin2, this prodecure uses the equation for 
 89    //                           determining the Theta -- or angle -- between the two and measures to see
 90    //                           if that angle is nearly zero. 
 91    //           NOTE:   In fact, it actually calculated COS(Theta) and check to see if it is close to 1.0
 92    //       RETURN: True if the Color Vector is similar to a skin-tone Vector, 
 93    //                           False otherwise
 94    public static boolean isFlesh (Color col)  {
 95        Vect Skin1 = new Vect (225, 165);
 96        Vect Skin2 = new Vect (125, 50);
 97        Vect curColor = new Vect (col.getRed(), col.getGreen());
 98        if ((col.getRed() < 40) || (col.getGreen() < 40))
 99            return false;
100        else if ((Math.abs(Vect.Theta(curColor, Skin1)) > 0.995) ||
101            (Math.abs(Vect.Theta(curColor, Skin2)) > 0.995)) 
102              return true;
103        else  return false;
104    }
105 }
106