View Javadoc

1   /**
2    * Copyright (c) 2011, The University of Southampton and the individual contributors.
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without modification,
6    * are permitted provided that the following conditions are met:
7    *
8    *   * 	Redistributions of source code must retain the above copyright notice,
9    * 	this list of conditions and the following disclaimer.
10   *
11   *   *	Redistributions in binary form must reproduce the above copyright notice,
12   * 	this list of conditions and the following disclaimer in the documentation
13   * 	and/or other materials provided with the distribution.
14   *
15   *   *	Neither the name of the University of Southampton nor the names of its
16   * 	contributors may be used to endorse or promote products derived from this
17   * 	software without specific prior written permission.
18   *
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package org.openimaj.demos.servotrack;
31  
32  import java.util.List;
33  
34  import org.openimaj.image.MBFImage;
35  import org.openimaj.image.colour.RGBColour;
36  import org.openimaj.image.processing.face.detection.DetectedFace;
37  import org.openimaj.image.processing.face.detection.HaarCascadeDetector;
38  import org.openimaj.math.geometry.point.Point2d;
39  import org.openimaj.math.geometry.point.Point2dImpl;
40  import org.openimaj.video.VideoDisplay;
41  import org.openimaj.video.VideoDisplayListener;
42  import org.openimaj.video.capture.VideoCapture;
43  
44  public class FaceTrack {
45  	public static void main(String[] args) throws Exception {
46  		final VideoCapture capture = new VideoCapture(640, 480, VideoCapture.getVideoDevices().get(0));
47  		final PTServoController servos = new PTServoController("/dev/tty.usbmodemfa131");
48  		final HaarCascadeDetector faceDetector = HaarCascadeDetector.BuiltInCascade.frontalface_alt2.load();
49  		faceDetector.setMinSize(80);
50  		final Point2d frameCentre = new Point2dImpl(capture.getWidth() / 2, capture.getHeight() / 2);
51  
52  		VideoDisplay.createVideoDisplay(capture).addVideoListener(new VideoDisplayListener<MBFImage>() {
53  
54  			@Override
55  			public void beforeUpdate(MBFImage frame) {
56  				if (frame == null)
57  					return;
58  
59  				final List<DetectedFace> faces = faceDetector.detectFaces(frame.flatten());
60  
61  				if (faces == null || faces.size() == 0) {
62  					// move back towards center
63  					final int tilt = (90 - servos.getTilt()) / 5;
64  					servos.changeTiltBy(tilt);
65  
66  					final int pan = (90 - servos.getPan()) / 5;
67  					servos.changePanBy(pan);
68  				} else {
69  					frame.drawShape(faces.get(0).getBounds(), RGBColour.RED);
70  
71  					// move towards face
72  					final Point2d pt = faces.get(0).getBounds().calculateCentroid();
73  
74  					final Point2d delta = pt.minus(frameCentre);
75  
76  					final double damp = 0.03;
77  
78  					if (delta.getX() < 0) {
79  						servos.changePanBy(-(int) (damp * delta.getX()));
80  					} else if (delta.getX() > 0) {
81  						servos.changePanBy(-(int) (damp * delta.getX()));
82  					}
83  
84  					if (delta.getY() < 0) {
85  						servos.changeTiltBy((int) (damp * delta.getY()));
86  					} else if (delta.getY() > 0) {
87  						servos.changeTiltBy((int) (damp * delta.getY()));
88  					}
89  				}
90  
91  				// try {
92  				// Thread.sleep(1500);
93  				// } catch (final InterruptedException e) {
94  				// // TODO Auto-generated catch block
95  				// e.printStackTrace();
96  				// }
97  			}
98  
99  			@Override
100 			public void afterUpdate(VideoDisplay<MBFImage> display) {
101 				// do nothing
102 			}
103 		});
104 
105 	}
106 }