<pre name="code" class="java">import org.opencv.core.*;
import org.opencv.face.Face;
import org.opencv.face.FaceRecognizer;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import java.io.File;
import java.io.FilenameFilter;
import java.util.*;
public class FaceTrainer {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
String trainingDir = "/home/test/faceData";
File[] imageFiles = getImagesFiles(trainingDir);
Map<Integer, String> idToNameMapping = createSummary(imageFiles);
ArrayList images = new ArrayList(imageFiles.length);
MatOfInt labelsBuf = new MatOfInt(new int[imageFiles.length]);
int counter = 0;
for (File image : imageFiles) {
// reads the training image in grayscale
Mat img = Imgcodecs.imread(image.getAbsolutePath(), Imgcodecs.CV_IMWRITE_JPEG_OPTIMIZE);
// gets the id of this image
int labelId = getIdFromImage(image.getName(), idToNameMapping);
// sets the image
images.add(getFaceMat(img));
labelsBuf.put(counter++, 0, labelId);
}
FaceRecognizer faceRecognizer = Face.createFisherFaceRecognizer();
// FaceRecognizer faceRecognizer = Face.createEigenFaceRecognizer();
// FaceRecognizer faceRecognizer = Face.createLBPHFaceRecognizer();
long start = System.nanoTime();
System.out.println(start + " : start");
faceRecognizer.train(images, labelsBuf);
long end = System.nanoTime();
System.out.println(end + " : end");
System.out.println(end - start + " : total");
// now we recognize a couple of faces
Mat testImageAndrea = Imgcodecs.imread("/home/test/att_faces/s1/1.pgm", Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
Mat testImageChiarina = Imgcodecs.imread("/home/test/att_faces/s1/2.pgm", Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
int predictedLabelAndrea = faceRecognizer.predict(testImageAndrea);
int predictedLabelChiarina = faceRecognizer.predict(testImageChiarina);
System.out.println("Predicted label andrea: " + idToNameMapping.get(predictedLabelAndrea));
System.out.println("Predicted label chiarina: " + idToNameMapping.get(predictedLabelChiarina));
}
public static Mat getFaceMat(Mat inputFrame) {
// Imgcodecs.imwrite("/tmp/" + new Random().nextInt(100) + ".pgm", inputFrame);
List<Mat> detectedElements = new ArrayList<Mat>(10);
Mat mRgba = new Mat();
Mat mGrey = new Mat();
inputFrame.copyTo(mRgba);
inputFrame.copyTo(mGrey);
MatOfRect results = new MatOfRect();
Imgproc.cvtColor( mRgba, mGrey, Imgproc.COLOR_BGR2GRAY);
Imgproc.equalizeHist( mGrey, mGrey );
CascadeClassifier cascadeClassifier =
new CascadeClassifier("/home/lwc/Documents/opencv-3.1.0/data/haarcascades/haarcascade_frontalface_alt.xml");
cascadeClassifier.detectMultiScale(mGrey, results);
Rect[] classifiedElements = results.toArray();
System.out.println("Dectected person: " + classifiedElements.length);
for (Rect rect : classifiedElements) {
// and adds it to the
Mat convert = new Mat();
Mat face = new Mat(mRgba.clone(), rect);
Imgproc.cvtColor(face, face, Imgproc.COLOR_BGR2GRAY);
face.convertTo(convert, Imgproc.COLOR_BGR2GRAY);
detectedElements.add(resizeFace(convert));
Imgcodecs.imwrite("/tmp/face" + new Random().nextInt(10)+ ".pgm", resizeFace(convert));
}
System.out.println("Get fave: " + detectedElements.size());
if(detectedElements.size() == 0) {
detectedElements.add(resizeFace(inputFrame));
}
return detectedElements.get(0);
}
public static Mat resizeFace(Mat originalImage) {
Mat resizedImage = new Mat();
Imgproc.resize(originalImage, resizedImage, new Size((double)92,(double)112));
return resizedImage;
}
private static File[] getImagesFiles(String trainingDir) {
File root = new File(trainingDir);
FilenameFilter imgFilter = (dir, name) -> {
name = name.toLowerCase();
return name.endsWith(".jpg") || name.endsWith(".pgm") || name.endsWith(".png");
};
return root.listFiles(imgFilter);
}
private static int getIdFromImage(String filename, Map<Integer, String> idToNameMapping) {
String name = filename.split("_")[0];
return idToNameMapping.keySet()
.stream()
.filter(id -> idToNameMapping.get(id).equals(name))
.findFirst()
.orElse(-1);
}
private static Map<Integer, String> createSummary(File[] imagesFiles) {
Map<Integer, String> idToNameMapping = new HashMap<>();
int idCounter = 0;
for (File imageFile : imagesFiles) {
String name = imageFile.getName().split("_")[0];
if (!idToNameMapping.values().contains(name)) {
idToNameMapping.put(idCounter++, name);
}
}
return idToNameMapping;
}
}