Sunday, July 23, 2017

Facial Recognition using Java

In this post, we will learn how to extract faces out of an image from webcam. We will make use of 2 library which are sarxos and openimaj

Language Used:
Java

Git Repo:
https://github.com/csanuragjain/extra/tree/master/FaceRecognition

Website:
https://cooltrickshome.blogspot.com/2017/07/facial-recognition-using-java.html

Pom Dependency:
 <dependency>  
   <groupId>org.openimaj</groupId>  
   <artifactId>image-feature-extraction</artifactId>  
   <version>1.3.5</version>  
 </dependency>  
 <dependency>  
      <artifactId>faces</artifactId>  
      <groupId>org.openimaj</groupId>  
      <version>1.3.5</version>  
      <scope>compile</scope>  
 </dependency>  
 <dependency>  
        <groupId>com.github.sarxos</groupId>  
        <artifactId>webcam-capture</artifactId>  
        <version>0.3.11</version>  
        <scope>test</scope>  
   </dependency>  

Reference:
https://cooltrickshome.blogspot.com/2016/11/take-snapshot-from-webcam-using-java-in.html
http://openimaj.org/

Program:

FaceDetector.java

Variables:
      private static final long serialVersionUID = 1L;  
      private static final HaarCascadeDetector detector = new HaarCascadeDetector();  
      private Webcam webcam = null;  
      private BufferedImage img= null;  
      private List<DetectedFace> faces = null;  


main method:
 public static void main(String[] args) throws IOException {  
           new FaceDetector().detectFace();  
      }  

How it works:
1) We create an object of FaceDetector class which class the default constructor and then we call the detectFace method of this class.

FaceDetector constructor:
      public FaceDetector() throws IOException {  
           webcam = Webcam.getDefault();  
           webcam.setViewSize(WebcamResolution.VGA.getSize());  
           webcam.open(true);  
           img=webcam.getImage();  
           webcam.close();  
           ImagePanel panel=new ImagePanel(img);  
           panel.setPreferredSize(WebcamResolution.VGA.getSize());  
           add(panel);  
           setTitle("Face Recognizer");  
           setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
           pack();  
           setLocationRelativeTo(null);  
           setVisible(true);  
      }  

How it works:
1) We use the sarxos library for webcam here
2) We create a webcam object and set the viewsize
3) We open the webcam using the open method
4) We take the image from webcam and store it into a BufferedImage object named img
5) Now we close the webcam and pass the image obtained in ImagePanel class which would then be added to Frame.
6) Now we show the frame to user with the webcam image which will be processed.

detectFace method:
      public void detectFace(){  
           JFrame fr=new JFrame("Discovered Faces");  
           faces = detector.detectFaces(ImageUtilities.createFImage(img));  
           if (faces == null) {  
                System.out.println("No faces found in the captured image");  
                return;  
           }  
           Iterator<DetectedFace> dfi = faces.iterator();  
           while (dfi.hasNext()) {  
                DetectedFace face = dfi.next();  
                FImage image1 = face.getFacePatch();  
                ImagePanel p=new ImagePanel(ImageUtilities.createBufferedImage(image1));  
                fr.add(p);  
           }  
           fr.setLayout(new FlowLayout(0));  
           fr.setSize(500,500);  
           fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
           fr.setVisible(true);  
      }  

How it works:
1) We use the openimaj library for face detection
2) We create a new Frame which would be showing up the results.
3) We make use of detectFaces method of HaarCascadeDetector class object detector, passing the image to be processed. ImageUtilities is used to create FImage out of BufferedImage.
4) If no face is found on image then an error message is returned.
5) Otherwise, we iterate through each face and retrieve the faces using getFacePatch method.
6) Again we use the createBufferedImage method of ImageUtilities class to get a BufferedImage out of FImage.
7) We add all the faces to the resulting frame.

ImagePanel Class:
 package com.cooltrickshome;  
 import java.awt.Dimension;  
 import java.awt.Graphics;  
 import java.awt.Image;  
 import javax.swing.ImageIcon;  
 import javax.swing.JPanel;  
 class ImagePanel  
  extends JPanel  
 {  
  private Image img;  
  public ImagePanel(String img)  
  {  
   this(new ImageIcon(img).getImage());  
  }  
  public ImagePanel(Image img)  
  {  
   this.img = img;  
   Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));  
   setPreferredSize(size);  
   setMinimumSize(size);  
   setMaximumSize(size);  
   setSize(size);  
   setLayout(null);  
  }  
  public void paintComponent(Graphics g)  
  {  
   g.drawImage(this.img, 0, 0, null);  
  }  
 }  

How it works:
1) This is used to show the image over a panel

Output:


Full Program:


FaceDetector.java
 package com.cooltrickshome;  
 /**  
  * Reference:  
  * https://github.com/sarxos/webcam-capture/tree/master/webcam-capture-examples/webcam-capture-detect-face  
  * http://openimaj.org/  
  */  
 import java.awt.FlowLayout;  
 import java.awt.image.BufferedImage;  
 import java.io.IOException;  
 import java.util.Iterator;  
 import java.util.List;  
 import javax.swing.JFrame;  
 import org.openimaj.image.FImage;  
 import org.openimaj.image.ImageUtilities;  
 import org.openimaj.image.processing.face.detection.DetectedFace;  
 import org.openimaj.image.processing.face.detection.HaarCascadeDetector;  
 import com.github.sarxos.webcam.Webcam;  
 import com.github.sarxos.webcam.WebcamResolution;  
 public class FaceDetector extends JFrame {  
      private static final long serialVersionUID = 1L;  
      private static final HaarCascadeDetector detector = new HaarCascadeDetector();  
      private Webcam webcam = null;  
      private BufferedImage img= null;  
      private List<DetectedFace> faces = null;  
      public FaceDetector() throws IOException {  
           webcam = Webcam.getDefault();  
           webcam.setViewSize(WebcamResolution.VGA.getSize());  
           webcam.open(true);  
           img=webcam.getImage();  
           webcam.close();  
           ImagePanel panel=new ImagePanel(img);  
           panel.setPreferredSize(WebcamResolution.VGA.getSize());  
           add(panel);  
           setTitle("Face Recognizer");  
           setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
           pack();  
           setLocationRelativeTo(null);  
           setVisible(true);  
      }  
      public void detectFace(){  
           JFrame fr=new JFrame("Discovered Faces");  
           faces = detector.detectFaces(ImageUtilities.createFImage(img));  
           if (faces == null) {  
                System.out.println("No faces found in the captured image");  
                return;  
           }  
           Iterator<DetectedFace> dfi = faces.iterator();  
           while (dfi.hasNext()) {  
                DetectedFace face = dfi.next();  
                FImage image1 = face.getFacePatch();  
                ImagePanel p=new ImagePanel(ImageUtilities.createBufferedImage(image1));  
                fr.add(p);  
           }  
           fr.setLayout(new FlowLayout(0));  
           fr.setSize(500,500);  
           fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
           fr.setVisible(true);  
      }  
      public static void main(String[] args) throws IOException {  
           new FaceDetector().detectFace();  
      }  
 }  

ImagePanel.java
 package com.cooltrickshome;  
 import java.awt.Dimension;  
 import java.awt.Graphics;  
 import java.awt.Image;  
 import javax.swing.ImageIcon;  
 import javax.swing.JPanel;  
 class ImagePanel  
  extends JPanel  
 {  
  private Image img;  
  public ImagePanel(String img)  
  {  
   this(new ImageIcon(img).getImage());  
  }  
  public ImagePanel(Image img)  
  {  
   this.img = img;  
   Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));  
   setPreferredSize(size);  
   setMinimumSize(size);  
   setMaximumSize(size);  
   setSize(size);  
   setLayout(null);  
  }  
  public void paintComponent(Graphics g)  
  {  
   g.drawImage(this.img, 0, 0, null);  
  }  
 }  

Hope it helps :)