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.KeyAdapter;
33 import java.awt.event.KeyEvent;
34 import java.io.File;
35 import java.io.IOException;
36 import java.util.List;
37
38 import javax.swing.JOptionPane;
39 import javax.swing.SwingUtilities;
40
41 import org.openimaj.feature.FloatFV;
42 import org.openimaj.feature.FloatFVComparison;
43 import org.openimaj.image.FImage;
44 import org.openimaj.image.MBFImage;
45 import org.openimaj.image.colour.RGBColour;
46 import org.openimaj.image.processing.face.alignment.CLMAligner;
47 import org.openimaj.image.processing.face.detection.CLMDetectedFace;
48 import org.openimaj.image.processing.face.feature.LocalLBPHistogram;
49 import org.openimaj.image.processing.face.feature.comparison.FaceFVComparator;
50 import org.openimaj.image.processing.face.feature.comparison.FacialFeatureComparator;
51 import org.openimaj.image.processing.face.recognition.AnnotatorFaceRecogniser;
52 import org.openimaj.image.processing.face.tracking.clm.CLMFaceTracker;
53 import org.openimaj.image.typography.hershey.HersheyFont;
54 import org.openimaj.io.IOUtils;
55 import org.openimaj.math.geometry.point.Point2d;
56 import org.openimaj.ml.annotation.AnnotatedObject;
57 import org.openimaj.ml.annotation.ScoredAnnotation;
58 import org.openimaj.ml.annotation.basic.KNNAnnotator;
59 import org.openimaj.video.VideoDisplay;
60 import org.openimaj.video.VideoDisplayListener;
61 import org.openimaj.video.capture.VideoCapture;
62
63 public class VideoFaceRecognition extends KeyAdapter implements VideoDisplayListener<MBFImage> {
64 private VideoCapture capture;
65 private VideoDisplay<MBFImage> videoFrame;
66
67 private AnnotatorFaceRecogniser<CLMDetectedFace, String> recogniser;
68 private CLMFaceTracker engine;
69 private FImage currentFrame;
70
71 public VideoFaceRecognition() throws Exception {
72 capture = new VideoCapture(320, 240);
73 engine = new CLMFaceTracker();
74 engine.fpd = 120;
75
76
77 videoFrame = VideoDisplay.createVideoDisplay(capture);
78 videoFrame.addVideoListener(this);
79 SwingUtilities.getRoot(videoFrame.getScreen()).addKeyListener(this);
80
81 final LocalLBPHistogram.Extractor<CLMDetectedFace> extractor = new
82 LocalLBPHistogram.Extractor<CLMDetectedFace>(
83 new CLMAligner(), 20, 20, 8, 1);
84 final FacialFeatureComparator<LocalLBPHistogram> comparator = new
85 FaceFVComparator<LocalLBPHistogram, FloatFV>(
86 FloatFVComparison.EUCLIDEAN);
87 final KNNAnnotator<CLMDetectedFace, String, LocalLBPHistogram> knn = KNNAnnotator.create(extractor, comparator,
88 1, 5f);
89
90
91
92
93
94
95
96
97
98
99 recogniser = AnnotatorFaceRecogniser.create(knn);
100 }
101
102 @Override
103 public synchronized void keyPressed(KeyEvent key) {
104 if (key.getKeyCode() == KeyEvent.VK_SPACE) {
105 this.videoFrame.togglePause();
106 } else if (key.getKeyChar() == 'c') {
107
108
109
110 final String person = JOptionPane.showInputDialog(this.videoFrame.getScreen(), "", "",
111 JOptionPane.QUESTION_MESSAGE);
112
113 final List<CLMDetectedFace> faces = detectFaces();
114 if (faces.size() == 1) {
115 recogniser.train(new AnnotatedObject<CLMDetectedFace, String>(faces.get(0), person));
116 } else {
117 System.out.println("Wrong number of faces found");
118 }
119
120
121 } else if (key.getKeyChar() == 'd') {
122 engine.reset();
123 }
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 else if (key.getKeyChar() == 's') {
139 try {
140 final File f = new File("rec.bin");
141 f.delete();
142 IOUtils.writeBinaryFull(f, this.recogniser);
143 } catch (final IOException e) {
144 e.printStackTrace();
145 }
146 } else if (key.getKeyChar() == 'l') {
147 try {
148 final File f = new File("rec.bin");
149 this.recogniser = IOUtils.read(f);
150 } catch (final IOException e) {
151
152 e.printStackTrace();
153 }
154 }
155 }
156
157 private List<CLMDetectedFace> detectFaces() {
158 return CLMDetectedFace.convert(engine.model.trackedFaces, currentFrame);
159 }
160
161 @Override
162 public void afterUpdate(VideoDisplay<MBFImage> display) {
163
164 }
165
166 @Override
167 public synchronized void beforeUpdate(MBFImage frame) {
168 this.currentFrame = frame.flatten();
169 engine.track(frame);
170 engine.drawModel(frame, true, true, true, true, true);
171
172 if (recogniser != null && recogniser.listPeople().size() >= 1) {
173 for (final CLMDetectedFace f : detectFaces()) {
174 final List<ScoredAnnotation<String>> name = recogniser.annotate(f);
175
176 if (name.size() > 0) {
177 final Point2d r = f.getBounds().getTopLeft();
178 frame.drawText(name.get(0).annotation, r, HersheyFont.ROMAN_SIMPLEX, 15, RGBColour.GREEN);
179 }
180 }
181 }
182 }
183
184 public static void main(String[] args) throws Exception {
185 new VideoFaceRecognition();
186 }
187 }