Javacv: FaceRecognizer failed to predict the face

Created on 4 Jul 2017  路  3Comments  路  Source: bytedeco/javacv

I have already trained images for almost three faces and saved the train data to HD, and then when loading the trained data, and predict the face, it throws the following the Exception:

java.lang.NullPointerException: Pointer address of argument 1 is NULL.
    at org.bytedeco.javacpp.opencv_face$FaceRecognizer.predict(Native Method)

The code:

BasicFaceRecognizer model = opencv_face.createEigenFaceRecognizer();
model.load("C:\\data\\eigen_faces.xml");
IntPointer label = new IntPointer();
DoublePointer confidence = new DoublePointer();
model.predict(face, label, confidence);
System.out.println(label.get());

But _the same code was working in OpenCV Java wrapper._

question

Most helpful comment

Thanks! The problem was exactly with both of them (IntPointer and DoublePointer) they both need to be initialized in the constructor.

_The code that I used the OpenCV is the same as the JavaCV, and also in OpenCV 3.3.0 version the Face class is no longer present, it means that the initialization of the face the recognizers is done by their classes, and not by the Face class._

The code:

private static void train() {
    List<Mat> imgs = new ArrayList<>();
    List<Integer> labelList = new ArrayList<>();
    MatOfInt labels = new MatOfInt();
    String pathToImages = "C:\\faces";

    File dir = new File(pathToImages);
    File[] dirs = dir.listFiles();
    int personCount = 1;
    assert dirs != null;
    for (File file : dirs) {
        File[] faces = file.listFiles();
        assert faces != null;
        for (File face : faces) {
            Mat faceMat = Imgcodecs.imread(face.getAbsolutePath(), Imgcodecs.IMREAD_GRAYSCALE);
            Imgproc.equalizeHist(faceMat, faceMat);
            imgs.add(faceMat);
            labelList.add(personCount);
        }
        personCount++;
    }
    labels.fromList(labelList);
    System.out.println(labels.dump());

    // train 
    //FaceRecognizer recognizer = Face.createEigenFaceRecognizer(); //80, 200
    FaceRecognizer recognizer = Face.createEigenFaceRecognizer();//4000
    //FaceRecognizer recognizer = Face.createLBPHFaceRecognizer();//3, 8, 8, 8, 180

    // label info
    String[] names = {"W-S", "B-A", "T-Y"};
    for (Integer integer : labelList) {
        recognizer.setLabelInfo(integer, names[integer-1]);
    }
    recognizer.train(imgs, labels);
    recognizer.save("C:\\face-data\\eigen-faces_trained_data.xml");
    //recognizer.save("C:\\face-data\\fisher-faces_trained_data.xml");
    //recognizer.save("C:\\face-data\\lbph-faces_trained_data.xml");
}

private static void recognize() {
    FaceRecognizer recognizer = Face.createEigenFaceRecognizer();
    recognizer.load("C:\\face-data\\eigen-faces_trained_data.xml");

    //FaceRecognizer recognizer = Face.createFisherFaceRecognizer();
    //recognizer.load("C:\\face-data\\fisher-faces_trained_data.xml");

    //FaceRecognizer recognizer = Face.createLBPHFaceRecognizer();
    //recognizer.load("C:\\face-data\\lbph-faces_trained_data.xml");

    //String filename = "E:\\haarcascades\\haarcascade_frontalface_alt_tree.xml";
    String filename = "E:\\haarcascades\\haarcascade_frontalcatface.xml";
    //String filename = "E:\\lbpcascades\\lbpcascade_frontalface_improved.xml";
    CascadeClassifier classifier = new CascadeClassifier(filename);
    VideoCapture capture = new VideoCapture(0);

    Mat frame = new Mat();
    Mat gray = new Mat();

    OpenCVUtil.VideoWindow window = OpenCVUtil.createWindow();
    MatOfRect faces  = new MatOfRect();
    int[] labels = new int[1];
    double[] confidences = new double[1];
    Size size = new Size(92, 112);
    while (capture.read(frame)) {
        //Imgproc.pyrDown(frame, frame);
        Imgproc.pyrDown(frame, frame);
        Imgproc.cvtColor(frame, gray, Imgproc.COLOR_BGR2GRAY);

        classifier.detectMultiScale(gray, faces);

        Rect[] rects = faces.toArray();
        Mat submat = null;

        System.out.println("");
        for (Rect rect : rects) {
            Imgproc.rectangle(frame, rect.tl(), rect.br(), new Scalar(0, 0, 255), 2);
            submat = gray.submat(rect).clone();
            Imgproc.equalizeHist(submat, submat);
            Imgproc.resize(submat, submat, size, 1, 1, Imgproc.INTER_CUBIC);

            recognizer.predict(submat, labels, confidences);
            int label = labels[0];
            double confidence = confidences[0];
            String labelInfo = recognizer.getLabelInfo(label);
            System.out.println("labelInfo = " + labelInfo);
            System.out.println("label = " + label);
            System.out.println("confidence = " + confidence);
            System.out.println("threshold = "+((BasicFaceRecognizer)recognizer).getThreshold());

            int x = (int) Math.max(rect.tl().x - 10, 0);
            int y = (int) Math.max(rect.tl().y - 10, 0);
            Imgproc.putText(frame, String.format("Predict = %s", labelInfo), new Point(x, y), Core.FONT_HERSHEY_PLAIN, 1.0, new Scalar(0, 255, 0), 2);
        }
        if (submat != null) {
            window.showVideo(capture, frame, gray, submat);
        } else {
            window.showVideo(capture, frame, gray);
        }
    }
    capture.release();
}

All 3 comments

Ok, please post the code that works, thanks!

The issue is probably with the IntPointer and DoublePointer though. Try this:

IntPointer label = new IntPointer(1);
DoublePointer confidence = new DoublePointer(1);

Thanks! The problem was exactly with both of them (IntPointer and DoublePointer) they both need to be initialized in the constructor.

_The code that I used the OpenCV is the same as the JavaCV, and also in OpenCV 3.3.0 version the Face class is no longer present, it means that the initialization of the face the recognizers is done by their classes, and not by the Face class._

The code:

private static void train() {
    List<Mat> imgs = new ArrayList<>();
    List<Integer> labelList = new ArrayList<>();
    MatOfInt labels = new MatOfInt();
    String pathToImages = "C:\\faces";

    File dir = new File(pathToImages);
    File[] dirs = dir.listFiles();
    int personCount = 1;
    assert dirs != null;
    for (File file : dirs) {
        File[] faces = file.listFiles();
        assert faces != null;
        for (File face : faces) {
            Mat faceMat = Imgcodecs.imread(face.getAbsolutePath(), Imgcodecs.IMREAD_GRAYSCALE);
            Imgproc.equalizeHist(faceMat, faceMat);
            imgs.add(faceMat);
            labelList.add(personCount);
        }
        personCount++;
    }
    labels.fromList(labelList);
    System.out.println(labels.dump());

    // train 
    //FaceRecognizer recognizer = Face.createEigenFaceRecognizer(); //80, 200
    FaceRecognizer recognizer = Face.createEigenFaceRecognizer();//4000
    //FaceRecognizer recognizer = Face.createLBPHFaceRecognizer();//3, 8, 8, 8, 180

    // label info
    String[] names = {"W-S", "B-A", "T-Y"};
    for (Integer integer : labelList) {
        recognizer.setLabelInfo(integer, names[integer-1]);
    }
    recognizer.train(imgs, labels);
    recognizer.save("C:\\face-data\\eigen-faces_trained_data.xml");
    //recognizer.save("C:\\face-data\\fisher-faces_trained_data.xml");
    //recognizer.save("C:\\face-data\\lbph-faces_trained_data.xml");
}

private static void recognize() {
    FaceRecognizer recognizer = Face.createEigenFaceRecognizer();
    recognizer.load("C:\\face-data\\eigen-faces_trained_data.xml");

    //FaceRecognizer recognizer = Face.createFisherFaceRecognizer();
    //recognizer.load("C:\\face-data\\fisher-faces_trained_data.xml");

    //FaceRecognizer recognizer = Face.createLBPHFaceRecognizer();
    //recognizer.load("C:\\face-data\\lbph-faces_trained_data.xml");

    //String filename = "E:\\haarcascades\\haarcascade_frontalface_alt_tree.xml";
    String filename = "E:\\haarcascades\\haarcascade_frontalcatface.xml";
    //String filename = "E:\\lbpcascades\\lbpcascade_frontalface_improved.xml";
    CascadeClassifier classifier = new CascadeClassifier(filename);
    VideoCapture capture = new VideoCapture(0);

    Mat frame = new Mat();
    Mat gray = new Mat();

    OpenCVUtil.VideoWindow window = OpenCVUtil.createWindow();
    MatOfRect faces  = new MatOfRect();
    int[] labels = new int[1];
    double[] confidences = new double[1];
    Size size = new Size(92, 112);
    while (capture.read(frame)) {
        //Imgproc.pyrDown(frame, frame);
        Imgproc.pyrDown(frame, frame);
        Imgproc.cvtColor(frame, gray, Imgproc.COLOR_BGR2GRAY);

        classifier.detectMultiScale(gray, faces);

        Rect[] rects = faces.toArray();
        Mat submat = null;

        System.out.println("");
        for (Rect rect : rects) {
            Imgproc.rectangle(frame, rect.tl(), rect.br(), new Scalar(0, 0, 255), 2);
            submat = gray.submat(rect).clone();
            Imgproc.equalizeHist(submat, submat);
            Imgproc.resize(submat, submat, size, 1, 1, Imgproc.INTER_CUBIC);

            recognizer.predict(submat, labels, confidences);
            int label = labels[0];
            double confidence = confidences[0];
            String labelInfo = recognizer.getLabelInfo(label);
            System.out.println("labelInfo = " + labelInfo);
            System.out.println("label = " + label);
            System.out.println("confidence = " + confidence);
            System.out.println("threshold = "+((BasicFaceRecognizer)recognizer).getThreshold());

            int x = (int) Math.max(rect.tl().x - 10, 0);
            int y = (int) Math.max(rect.tl().y - 10, 0);
            Imgproc.putText(frame, String.format("Predict = %s", labelInfo), new Point(x, y), Core.FONT_HERSHEY_PLAIN, 1.0, new Scalar(0, 255, 0), 2);
        }
        if (submat != null) {
            window.showVideo(capture, frame, gray, submat);
        } else {
            window.showVideo(capture, frame, gray);
        }
    }
    capture.release();
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

kongqw picture kongqw  路  4Comments

myScoopAndroidCamera picture myScoopAndroidCamera  路  4Comments

The-Crocop picture The-Crocop  路  5Comments

chenhl05 picture chenhl05  路  4Comments

SenudaJayalath picture SenudaJayalath  路  3Comments