Ask Your Question
0

OpenCV in JAVA about using face recognizer

asked 2017-12-10 21:19:36 -0600

zzywd01 gravatar image

updated 2017-12-10 23:45:03 -0600

Hey guys, I'm recently learning OpenCV. I met a problem when I want to recognize a face using the FaceRecognizer function. I tried to train the classifier with the sample from internet(from yale), but I keep getting wrong prediction (in fact it only output category "1") when I input one of the training picture as test sample. Could anyone give me some hint? I attached my code below. Thanks a lot!

(I think the problem might be the training samples as they are already grayscaled. I grayscaled them again because the error "bad arguement, size(1,30000), (10000,66)...." thing shows up If I don't do so.)

import org.opencv.face.FaceRecognizer;
import org.opencv.core.Mat;
import org.opencv.core.MatOfInt;
import org.opencv.core.*;
import org.opencv.face.Face;
import org.opencv.imgcodecs.Imgcodecs;
import java.io.File;  
import java.io.FilenameFilter;  
import java.util.List;
import java.util.ArrayList;
import org.opencv.imgproc.Imgproc;


public class FaceRecognization {
    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);  
        String trainingDir = "C:\\Users\\songli\\Desktop\\yale\\train";
        String testImgPath = "C:\\Users\\songli\\Desktop\\yale\\5-6.bmp";
        Mat testImg = Imgcodecs.imread(testImgPath);
        Mat gray = new Mat();
        File root = new File(trainingDir);
        FilenameFilter bmpFilter = new FilenameFilter(){
            public boolean accept(File dir, String name){
                return name.toLowerCase().endsWith(".bmp");
            }
        };

        File[] imageFiles = root.listFiles(bmpFilter);
        List<Mat> list = new ArrayList<Mat>(imageFiles.length);
        int[] labels = new int[imageFiles.length];

        int counter = 0;
        int label;
        Mat grayImg = new Mat();
        Mat grayTestImg = new Mat();
        Mat img = new Mat();
        for(File image : imageFiles){
            img = Imgcodecs.imread(image.getAbsolutePath());
            //System.out.print(img.elemSize());
            label = Integer.parseInt(image.getName().split("\\-")[0]);
            grayImg.create(img.width(), img.height(),1);
            Imgproc.cvtColor(img, grayImg, Imgproc.COLOR_BGR2GRAY);  
            list.add(grayImg);
            labels[counter] = label;
            counter++;
        }
        //System.out.print(labels[11]);
        MatOfInt labels1 = new MatOfInt();
        labels1.fromArray(labels);
        FaceRecognizer fr = Face.createEigenFaceRecognizer();
        fr.train(list,labels1);
        grayTestImg.create(testImg.width(),testImg.height(),1);
        Imgproc.cvtColor(testImg,grayTestImg,Imgproc.COLOR_BGR2GRAY);

        int predictedlabel = fr.predict_label(grayTestImg);
        //Imgcodecs.imwrite("C:\\Users\\songli\\Desktop\\testImg.jpg", testImg);





        //int[] predLabel = new int[1];
        //double[] confidence = new double[1];
        //int result = -1;
        //fr.predict(testImgGrey,predLabel,confidence);
        //result = predLabel[0];
        System.out.println("Predicted label: " + predictedlabel);  





    }
}
edit retag flag offensive close merge delete

Comments

it's probably unrelated, but:

grayImg.create(img.width(), img.height(),1);

please don't do that, it's not nessecary, and you got ALL params wrong ! just use:

grayImg = new Mat()

(same for the train images)

berak gravatar imageberak ( 2017-12-11 07:36:48 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2017-12-11 08:20:05 -0600

berak gravatar image

updated 2017-12-11 08:27:33 -0600

the problem is NOT opencv's FaceRocognizer here, but that you train it on 200 instances of the same image !

let me show you:

java.util.List<Mat> list = new ArrayList<Mat>();
Mat img = new Mat(); // this is the problem

for(int i=0; i<5; i++){
    img.create(3,3,0);
    img.setTo(new Scalar(i));
    list.add(img); // they're all the same here ! (no "deep copy")
}

for (Mat i:list) {
    System.out.println(i.dump());
}

 [java] [  4,   4;
 [java]    4,   4]
 [java] [  4,   4;
 [java]    4,   4]
 [java] [  4,   4;
 [java]    4,   4]
 [java] [  4,   4;
 [java]    4,   4]
 [java] [  4,   4;
 [java]    4,   4

remedy: use local variables in your for loop:

    for(File image : imageFiles){
        Mat img = Imgcodecs.imread(image.getAbsolutePath());
        Mat grayImg = new Mat();
        Imgproc.cvtColor(img, grayImg, Imgproc.COLOR_BGR2GRAY);  
        list.add(grayImg);
       ...
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-12-10 21:16:55 -0600

Seen: 1,121 times

Last updated: Dec 11 '17