1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.openimaj.demos.video.videosift;
31
32 import java.awt.event.KeyEvent;
33 import java.awt.event.KeyListener;
34 import java.util.List;
35
36 import javax.swing.SwingUtilities;
37
38 import org.openimaj.demos.video.utils.PolygonDrawingListener;
39 import org.openimaj.image.FImage;
40 import org.openimaj.image.MBFImage;
41 import org.openimaj.image.colour.RGBColour;
42 import org.openimaj.image.colour.Transforms;
43 import org.openimaj.image.processing.face.detection.DetectedFace;
44 import org.openimaj.image.processing.face.detection.FaceDetector;
45 import org.openimaj.image.processing.face.detection.HaarCascadeDetector;
46 import org.openimaj.image.processing.face.detection.keypoints.FKEFaceDetector;
47 import org.openimaj.image.processing.face.detection.keypoints.FacialKeypoint;
48 import org.openimaj.image.processing.face.detection.keypoints.KEDetectedFace;
49 import org.openimaj.image.renderer.MBFImageRenderer;
50 import org.openimaj.math.geometry.point.Point2d;
51 import org.openimaj.math.geometry.shape.Rectangle;
52 import org.openimaj.math.geometry.shape.Shape;
53 import org.openimaj.video.VideoDisplay;
54 import org.openimaj.video.VideoDisplayListener;
55 import org.openimaj.video.capture.VideoCapture;
56
57 public class VideoFace implements VideoDisplayListener<MBFImage>, KeyListener {
58 private VideoCapture capture;
59 private VideoDisplay<MBFImage> videoFrame;
60
61 private FaceDetector<DetectedFace, FImage> innerEngine;
62 private FKEFaceDetector engine;
63
64 private PolygonDrawingListener polygonListener;
65
66 boolean findKeypoints = false;
67
68 public VideoFace() throws Exception {
69 capture = new VideoCapture(320, 240);
70
71 innerEngine = new HaarCascadeDetector();
72 engine = new FKEFaceDetector(innerEngine);
73
74 polygonListener = new PolygonDrawingListener();
75 videoFrame = VideoDisplay.createVideoDisplay(capture);
76 videoFrame.getScreen().addMouseListener(polygonListener);
77 videoFrame.addVideoListener(this);
78 SwingUtilities.getRoot(videoFrame.getScreen()).addKeyListener(this);
79 }
80
81 @Override
82 public void afterUpdate(VideoDisplay<MBFImage> display) {
83
84 }
85
86 @Override
87 public synchronized void beforeUpdate(MBFImage frame) {
88 List<? extends DetectedFace> faces = null;
89 if (findKeypoints) {
90 faces = engine
91 .detectFaces(Transforms.calculateIntensityNTSC(frame));
92 } else {
93 faces = innerEngine.detectFaces(Transforms
94 .calculateIntensityNTSC(frame));
95 }
96
97 if (faces.size() > 0) {
98 Rectangle r = faces.get(0).getBounds();
99 ((HaarCascadeDetector) innerEngine)
100 .setMinSize((int) (r.width * 0.9));
101 } else {
102 ((HaarCascadeDetector) innerEngine).setMinSize(1);
103 }
104
105 for (DetectedFace face : faces) {
106 final Shape bounds = face.getBounds();
107
108 MBFImageRenderer renderer = frame.createRenderer();
109 renderer.drawPolygon(bounds.asPolygon(), RGBColour.RED);
110
111 if (findKeypoints) {
112 for (FacialKeypoint kp : ((KEDetectedFace) face).getKeypoints()) {
113 Point2d pt = kp.position.clone();
114 pt.translate((float) bounds.minX(), (float) bounds.minY());
115
116 renderer.drawPoint(pt, RGBColour.GREEN, 3);
117 }
118 }
119 }
120 }
121
122 @Override
123 public void keyTyped(KeyEvent e) {
124
125 }
126
127 @Override
128 public synchronized void keyPressed(KeyEvent e) {
129 if (e.getKeyChar() == 't') {
130 findKeypoints = !findKeypoints;
131 }
132 }
133
134 @Override
135 public void keyReleased(KeyEvent e) {
136
137 }
138
139 public static void main(String[] args) throws Exception {
140 new VideoFace();
141 }
142 }