Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java and haarcascade face and mouth detection - mouth as the nose

Today I begin to test the project which detects a smile in Java and OpenCv. To recognition face and mouth project used haarcascade_frontalface_alt and haarcascade_mcs_mouth But i don't understand why in some reasons project detect nose as a mouth. I have two methods:

private ArrayList<Mat> detectMouth(String filename) {
    int i = 0;
    ArrayList<Mat> mouths = new ArrayList<Mat>();
    // reading image in grayscale from the given path
    image = Highgui.imread(filename, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
    MatOfRect faceDetections = new MatOfRect();
    // detecting face(s) on given image and saving them to MatofRect object
    faceDetector.detectMultiScale(image, faceDetections);
    System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
    MatOfRect mouthDetections = new MatOfRect();
    // detecting mouth(s) on given image and saving them to MatOfRect object
    mouthDetector.detectMultiScale(image, mouthDetections);
    System.out.println(String.format("Detected %s mouths", mouthDetections.toArray().length));
    for (Rect face : faceDetections.toArray()) {
        Mat outFace = image.submat(face);
        // saving cropped face to picture
        Highgui.imwrite("face" + i + ".png", outFace);
        for (Rect mouth : mouthDetections.toArray()) {
            // trying to find right mouth
            // if the mouth is in the lower 2/5 of the face
            // and the lower edge of mouth is above of the face
            // and the horizontal center of the mouth is the enter of the face
            if (mouth.y > face.y + face.height * 3 / 5 && mouth.y + mouth.height < face.y + face.height
                    && Math.abs((mouth.x + mouth.width / 2)) - (face.x + face.width / 2) < face.width / 10) {
                Mat outMouth = image.submat(mouth);
                // resizing mouth to the unified size of trainSize
                Imgproc.resize(outMouth, outMouth, trainSize);
                mouths.add(outMouth);
                // saving mouth to picture 
                Highgui.imwrite("mouth" + i + ".png", outMouth);
                i++;
            }
        }
    }
    return mouths;
}

and detect smile

private void detectSmile(ArrayList<Mat> mouths) {
        trainSVM();
        CvSVMParams params = new CvSVMParams();
        // set linear kernel (no mapping, regression is done in the original feature space)
        params.set_kernel_type(CvSVM.LINEAR);
    // train SVM with images in trainingImages, labels in trainingLabels, given params with empty samples
        clasificador = new CvSVM(trainingImages, trainingLabels, new Mat(), new Mat(), params);
        // save generated SVM to file, so we can see what it generated
        clasificador.save("svm.xml");
        // loading previously saved file
        clasificador.load("svm.xml");
        // returnin, if there aren't any samples
        if (mouths.isEmpty()) {
            System.out.println("No mouth detected");
            return;
        }
        for (Mat mouth : mouths) {
            Mat out = new Mat();
            // converting to 32 bit floating point in gray scale
            mouth.convertTo(out, CvType.CV_32FC1);
            if (clasificador.predict(out.reshape(1, 1)) == 1.0) {
                System.out.println("Detected happy face");
            } else {
                System.out.println("Detected not a happy face");
            }
        }
    }

Examples:

For that picture

enter image description here

correctly detects this mounth:

enter image description here

but in other picture

enter image description here

nose is detected enter image description here

What's the problem in your opinion ?

like image 200
Adamo Avatar asked Jun 20 '16 11:06

Adamo


1 Answers

Most likely it detects it wrong on your picture, because of proportion of face (too long distance from eyes to mouth compared to distance between eyes). Detection of mouth and nose using haar detector isn't very stable, so algorithms usually use geometry model of face, to choose best combination of feature candidates for each facial feature. Some implementations can even try to predict mouth position based on eyes, if no mouth candidates was found.

Haar detector isn't the newest and best known at this time for feature detection. Try to use deformable parts model implementations. Try this, they have matlab code with efficient c++ optimized functions: https://www.ics.uci.edu/~xzhu/face/

like image 115
taarraas Avatar answered Oct 12 '22 01:10

taarraas