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;
31
32 import java.io.BufferedWriter;
33 import java.io.DataInput;
34 import java.io.DataOutput;
35 import java.io.File;
36 import java.io.FileWriter;
37 import java.io.IOException;
38 import java.util.ArrayList;
39 import java.util.List;
40
41 import org.apache.commons.io.IOUtils;
42 import org.openimaj.image.FImage;
43 import org.openimaj.image.ImageUtilities;
44 import org.openimaj.image.processing.face.alignment.AffineAligner;
45 import org.openimaj.image.processing.face.alignment.FaceAligner;
46 import org.openimaj.image.processing.face.detection.DetectedFace;
47 import org.openimaj.image.processing.face.detection.FaceDetector;
48 import org.openimaj.image.processing.face.detection.keypoints.FKEFaceDetector;
49 import org.openimaj.image.processing.face.detection.keypoints.KEDetectedFace;
50 import org.openimaj.math.geometry.shape.Rectangle;
51 import org.openimaj.util.function.Operation;
52 import org.openimaj.util.parallel.Parallel;
53
54 import scala.actors.threadpool.Arrays;
55
56 public class FVFWDetectAlign {
57 static interface FDFactory {
58 FKEFaceDetector create();
59 }
60
61 @SuppressWarnings("unchecked")
62 private static void extractFaces(final File indir, final File outDir, final FDFactory factory,
63 final FaceAligner<KEDetectedFace> aligner) throws IOException
64 {
65 final List<String> skipped = new ArrayList<String>();
66
67 Parallel.forEach(Arrays.asList(indir.listFiles()), new Operation<File>() {
68
69 @Override
70 public void perform(File dir) {
71 try {
72 if (!dir.isDirectory())
73 return;
74
75 final FKEFaceDetector detector = factory.create();
76
77 for (final File imgfile : dir.listFiles()) {
78 if (!imgfile.getName().endsWith(".jpg"))
79 continue;
80
81 System.out.println(imgfile);
82 final File outfile = new File(outDir, imgfile.getAbsolutePath().replace(indir.getAbsolutePath(),
83 ""));
84 outfile.getParentFile().mkdirs();
85
86 final FImage aligned = extractAndAlignFace(ImageUtilities.readF(imgfile), detector, aligner);
87
88 if (aligned == null) {
89 synchronized (skipped) {
90 skipped.add(imgfile.toString());
91 }
92 } else {
93 ImageUtilities.write(aligned, outfile);
94 }
95 }
96 } catch (final Exception e) {
97 e.printStackTrace();
98 System.err.println(e);
99 }
100 }
101 });
102
103 final BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outDir, "skipped.txt")));
104 IOUtils.writeLines(skipped, "\n", writer);
105 writer.close();
106 }
107
108 private static FImage
109 extractAndAlignFace(FImage img, FKEFaceDetector detector, FaceAligner<KEDetectedFace> aligner)
110 {
111 final List<KEDetectedFace> faces = detector.detectFaces(img);
112
113 if (faces.size() == 1)
114 return aligner.align(faces.get(0));
115
116 return null;
117 }
118
119
120
121
122
123 public static void main(String[] args) throws IOException {
124 final FDFactory factory = new FDFactory() {
125 @Override
126 public FKEFaceDetector create() {
127 final FaceDetector<DetectedFace, FImage> inner = new FaceDetector<DetectedFace, FImage>() {
128 @Override
129 public void readBinary(DataInput in) throws IOException {
130
131 }
132
133 @Override
134 public byte[] binaryHeader() {
135 return null;
136 }
137
138 @Override
139 public void writeBinary(DataOutput out) throws IOException {
140
141 }
142
143 @Override
144 public List<DetectedFace> detectFaces(FImage image) {
145 final List<DetectedFace> faces = new ArrayList<DetectedFace>();
146
147 final int dw = Math.round(image.width / 2.2f);
148 final int dh = Math.round(image.height / 2.2f);
149 final int x = (image.width - dw) / 2;
150 final int y = (image.height - dh) / 2;
151 final Rectangle bounds = new Rectangle(x, y, dw, dh);
152
153 faces.add(new DetectedFace(bounds, image.extractROI(bounds), 1f));
154
155 return faces;
156 }
157 };
158
159 return new FKEFaceDetector(inner, 1.5f);
160 }
161 };
162
163 final AffineAligner aligner = new AffineAligner(125, 160, 0.1f);
164
165 extractFaces(new File("/Volumes/Raid/face_databases/lfw"), new File(
166 "/Volumes/Raid/face_databases/lfw-centre-affine/"), factory, aligner);
167 }
168 }