I couldn’t find any tutorial on how to perform face recognition using OpenCV and Java, so I decided to share a viable solution here. The solution is very inefficient in its current form as the training model is built at each run, however it shows what’s needed to make it work.

The class below takes two arguments: The path to the directory containing the training faces and the path to the image you want to classify. Not that all images has to be of the same size and that the faces already has to be cropped out of their original images (Take a look here if you haven’t done the face detection yet).

For the simplicity of this post, the class also requires that the training images have filename format:

1-jon_doe_1.png
1-jon_doe_2.png
2-jane_doe_1.png
2-jane_doe_2.png
…and so on.

The code:

import com.googlecode.javacv.cpp.opencv_core;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_contrib.*;
import java.io.File;
import java.io.FilenameFilter;

public class OpenCVFaceRecognizer {
    public static void main(String[] args) {
        String trainingDir = args[0];
        IplImage testImage = cvLoadImage(args[1]);

        File root = new File(trainingDir);

        FilenameFilter pngFilter = new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".png");
            }
        };

        File[] imageFiles = root.listFiles(pngFilter);

        MatVector images = new MatVector(imageFiles.length);

        int[] labels = new int[imageFiles.length];

        int counter = 0;
        int label;

        IplImage img;
        IplImage grayImg;

        for (File image : imageFiles) {
            img = cvLoadImage(image.getAbsolutePath());

            label = Integer.parseInt(image.getName().split("\\-")[0]);

            grayImg = IplImage.create(img.width(), img.height(), IPL_DEPTH_8U, 1);

            cvCvtColor(img, grayImg, CV_BGR2GRAY);

            images.put(counter, grayImg);

            labels[counter] = label;

            counter++;
        }

        IplImage greyTestImage = IplImage.create(testImage.width(), testImage.height(), IPL_DEPTH_8U, 1);

        FaceRecognizer faceRecognizer = createFisherFaceRecognizer();
        // FaceRecognizer faceRecognizer = createEigenFaceRecognizer();
        // FaceRecognizer faceRecognizer = createLBPHFaceRecognizer()

        faceRecognizer.train(images, labels);

        cvCvtColor(testImage, greyTestImage, CV_BGR2GRAY);

        int predictedLabel = faceRecognizer.predict(greyTestImage);

        System.out.println("Predicted label: " + predictedLabel);
    }
}

The class requires the OpenCV Java interface. If you’re using Maven, you can retrieve the required libraries with the following pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.pcbje</groupId>
    <artifactId>opencvfacerecognizer</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>opencvfacerecognizer</name>
    <url>http://pcbje.com</url>

    <dependencies>
        <dependency>
            <groupId>com.googlecode.javacv</groupId>
            <artifactId>javacv</artifactId>
            <version>0.3</version>
        </dependency>

        <!-- For Linux x64 environments -->
        <dependency>
            <groupId>com.googlecode.javacv</groupId>
            <artifactId>javacv</artifactId>
            <classifier>linux-x86_64</classifier>
            <version>0.3</version>
        </dependency>

        <!-- For OSX environments -->
        <dependency>
            <groupId>com.googlecode.javacv</groupId>
            <artifactId>javacv</artifactId>
            <classifier>macosx-x86_64</classifier>
            <version>0.3</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>javacv</id>
            <name>JavaCV</name>
            <url>http://maven2.javacv.googlecode.com/git/</url>
        </repository>
    </repositories>
</project>