Ask Your Question

Revision history [back]

OpenCV FaceRecognizer 3.3.0 with java, Mismatching images.

I have a few test images(13) in file(dir) and 50 trained images in another file(trainingDir).
When I try to test the test images with the trained images list, a few are matching (labels are returned correctly) but a few are mismatching even though they are existed.
How to find it out the mismatched images by passing threshold to the constructor.

when I pass threshold and no. of components(eigen faces), something goes wrong with matched labels. They are mismatching then, predicted labels are wrongly returned .
How to avoid these mismatching.
Below is my code:

public class OpenCVFaceRecognizer {

static File dir = new File("/home/venkatesh/Pictures/FR-Images/Test1");
static String trainingDir = "/home/venkatesh/Pictures/FR-Images/trainingFaces";

public static void main(String[] args) {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    if (dir.isDirectory()) {
       File[] listFiles = dir.listFiles();
       Arrays.sort(listFiles);
        for (final File f : listFiles) {
            predictFace(f);
        }
    }else{
        System.out.println("Not a directory!!");
        System.exit(0);
    }
}

public static void predictFace(File f){
    Mat testImage = imread(f.getAbsolutePath(), Imgproc.COLOR_GRAY2RGB);

    File root = new File(trainingDir);
    FilenameFilter imgFilter = new FilenameFilter() {
        public boolean accept(File dir, String name) {
            name = name.toLowerCase();
            return name.endsWith(".jpg") || name.endsWith(".pgm") || name.endsWith(".png");
        }
    };

    File[] imageFiles = root.listFiles(imgFilter);
    Vector<Mat> images =new Vector<>(imageFiles.length);
    Mat labels = new Mat(imageFiles.length, 1, CV_32SC1);
    int counter = 0;
    for (File image : imageFiles) {
        Mat img = imread(image.getAbsolutePath(), CV_LOAD_IMAGE_GRAYSCALE);
        int label = Integer.parseInt(image.getName().split("_")[0]);
        images.add(counter, img);
        labels.put(counter,0, label);
        counter++;
    }

    FaceRecognizer faceRecognizer = EigenFaceRecognizer.create();
    faceRecognizer.train(images, labels);
    int[] label = {-1};
    double[] confidence = {0.0};
    faceRecognizer.predict(testImage, label, confidence);
    int predictedLabel = label[0];

    System.out.println("Predicted label: " + predictedLabel + " Distance :"+ confidence[0]/1000);
}

}

Output:

  1. Predicted label: 76 Distance :0.6879670545920532
  2. Predicted label: 76 Distance :1.2013331537399639
  3. Predicted label: 76 Distance :1.863555635130535
  4. Predicted label: 88 Distance :2.3640474213981806
  5. Predicted label: 66 Distance :2.9285842098873553
  6. Predicted label: 66 Distance :2.3156894397998764
  7. Predicted label: 66 Distance :2.525213592806841
  8. Predicted label: 79 Distance :2.3647210914286783
  9. Predicted label: 92 Distance :3.8993551613685513
  10. Predicted label: 79 Distance :3.8066827136184176
  11. Predicted label: 92 Distance :4.443677492587241
  12. Predicted label: 88 Distance :2.949079331858225
  13. Predicted label: 88 Distance :3.1199972445479807

In output, 10th one is mismatched. (79 instead of 92).

To avoid this mismatching, I have passed parameters into constructor
changed code is below:

    FaceRecognizer faceRecognizer = EigenFaceRecognizer.create(1, 110);
    faceRecognizer.train(images, labels);
    int[] label = {-1};
    double[] confidence = {0.0};
    faceRecognizer.predict(testImage, label, confidence);
    int predictedLabel = label[0];

    System.out.println("Predicted label: " + predictedLabel + " Distance :"+ confidence[0]/1000);

In create(1, 110), 1 is no. of components and 110 is threshold.
Output:

  1. Predicted label: 76 Distance :0.010607112241999062
  2. Predicted label: 76 Distance :0.00935673483193318
  3. Predicted label: 76 Distance :0.0245086870763173
  4. Predicted label: 79 Distance :0.026988126077856122
  5. Predicted label: 88 Distance :0.008182496766205987
  6. Predicted label: 88 Distance :0.012984324699383251
  7. Predicted label: 88 Distance :0.0011827737487510603
  8. Predicted label: 79 Distance :0.009255683204992692
  9. Predicted label: 88 Distance :0.041966132865250985
  10. Predicted label: 66 Distance :0.10178422613652219
  11. Predicted label: 88 Distance :0.024852483796071963
  12. Predicted label: 88 Distance :4.732946291351254E-4
  13. Predicted label: 79 Distance :0.014748403217882696

If we compare the output with previous output, a few labels are mismatched.
Am I not passing the values into constructor correctly (tried with random values to predict the output)?
I have no proper idea that what values to be passed for no. of components and threshold

  1. Can I know what values to be passed as no. of components and threshold value in my case.
  2. I want the distance is -1 for mismatched images and 0 for matched images for the predicted labels
    Can anyone help me please.
    Thank you.