/* * TP VAP ASR - CSC5004 * Copyright (C) 2009-2010 Institut TELECOM ; TELECOM Sudparis * All rights reserved. * Author: S. LERICHE - sebastien.leriche@it-sudparis.eu * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the Institut TELECOM, TELECOM SudParis nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import hypermedia.video.OpenCV; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.image.BufferStrategy; import java.awt.image.MemoryImageSource; import java.util.Vector; import javax.swing.JFrame; public class FaceDetection extends JFrame implements Runnable { private static final long serialVersionUID = 1L; // program execution frame rate (millisecond) final int FRAME_RATE = 200; OpenCV cv = null; // OpenCV Object Thread t = null; // the sample thread private Image icon; // the input video stream image Image frame = null; // list of all face detected area Rectangle[] squares = new Rectangle[0]; private Boolean hasFace; private boolean oldFace; private Vector<FaceListener> vectFaceListener; private int iw; private int ih; private Font font = new Font("Arial", Font.BOLD, 18); private BufferStrategy strategy; private Graphics2D buffer; /** * Setup Frame and Object(s). */ FaceDetection() { super("Détection de visages - Fête de la Science 2009"); vectFaceListener = new Vector<FaceListener>(); // OpenCV setup cv = new OpenCV(); cv.capture(320, 240); cv.cascade(OpenCV.CASCADE_FRONTALFACE_ALT); // frame setup // this.setBounds(100, 100, cv.width * 2, cv.height * 2); // this.setBackground(Color.WHITE); // this.setVisible(true); // this.addKeyListener(new KeyAdapter() { // public void keyReleased(KeyEvent e) { // if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { // ESC : release // // OpenCV resources // cv.dispose(); // try { // Thread.sleep(1000); // } catch (InterruptedException e1) { // // TODO Auto-generated catch block // e1.printStackTrace(); // } // System.exit(0); // } // } // }); // // setDefaultCloseOperation(EXIT_ON_CLOSE); // // Dimension tailleEcran = java.awt.Toolkit.getDefaultToolkit() // .getScreenSize(); // int sizeX = tailleEcran.width * 2 / 3; // int sizeY = Math.round(sizeX / (float) 1.33); // int PSizeX = getPreferredSize().width; // int PSizeY = getPreferredSize().height; // // setSize(Math.min(tailleEcran.width, Math.max(sizeX, PSizeX)), Math.min( // tailleEcran.height, Math.max(sizeY, PSizeY))); // setLocationRelativeTo(null); // // ImageIcon aux = new ImageIcon("logo_TSP.gif"); // if (aux != null) { // icon = aux.getImage(); // } // if (icon != null) { // setIconImage(icon); // } // iw = icon.getWidth(null); // ih = icon.getHeight(null); // // // inhibe la méthode courante d'affichage du composant // setIgnoreRepaint(true); // // // on créé 2 buffers dans la VRAM donc c'est du double-buffering // createBufferStrategy(2); // // // récupère les buffers graphiques dans la mémoire VRAM // strategy = getBufferStrategy(); // buffer = (Graphics2D) strategy.getDrawGraphics(); // // this.setResizable(false); // start running program t = new Thread(this); t.start(); } /** * Draw video frame and each detected faces area. */ public void render() { RenderingHints r = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED); buffer.setRenderingHints(r); // draw image // g2.drawImage( frame, 0, 0, null ); buffer.drawImage(frame, 0, 0, getWidth(), getHeight(), 0, 0, cv.width, cv.height, null); float rw = getWidth() / (float) cv.width; float rh = getHeight() / (float) cv.height; buffer.setColor(Color.BLACK); buffer.setFont(font); buffer.drawImage(icon, getWidth() - iw - 50, getHeight() - ih - 50, iw, ih, null); buffer.drawString("Département INFormatique", getWidth() - iw - 350, getHeight() - 40); buffer.drawString("Conception et réalisation : Sébastien Leriche", getWidth() - iw - 350, getHeight() - 20); // draw squares buffer.setColor(Color.RED); for (Rectangle rect : squares) buffer.drawRect(Math.round(rect.x * rw), Math.round(rect.y * rh), Math.round(rect.width * rw), Math.round(rect.height * rh)); strategy.show(); } /** * Execute this sample. */ public void run() { while (t != null && cv != null) { // grab image from video stream cv.read(); // create a new image from cv pixels data MemoryImageSource mis = new MemoryImageSource(cv.width, cv.height, cv.pixels(), 0, cv.width); frame = createImage(mis); this.oldFace = getFace(); // detect faces squares = cv.detect(1.2f, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 20, 20); this.hasFace = getFace(); if (oldFace != hasFace) { fireFaceEvent(); } // of course, render //render(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void fireFaceEvent() { if(!vectFaceListener.isEmpty()) { FaceEvent fe = new FaceEvent(this, this.hasFace); for (FaceListener fl : vectFaceListener) { fl.FaceAlarm(fe); } } } public void addFaceListener(FaceListener tl) { this.vectFaceListener.add(tl); } public void removeFaceListener(FaceListener tl) { this.vectFaceListener.remove(tl); } public boolean getFace() { if (squares.length == 0) { return false; } else { return true; } } public Boolean hasFace() { return this.hasFace; } /** * Main method. * * @param String * [] a list of user's arguments passed from the console to this * program */ public static void main(String[] args) { System.out.println("\nOpenCV face detection sample\n"); new FaceDetection(); } }