【问题标题】:Java and haarcascade face and mouth detection - mouth as the noseJava和haarcascade人脸和嘴巴检测——嘴巴当鼻子
【发布时间】:2016-10-21 16:09:24
【问题描述】:

今天我开始测试在 Java 和 OpenCv 中检测微笑的项目。识别面部和嘴巴项目使用 haarcascade_frontalface_alt 和 haarcascade_mcs_mouth 但我不明白为什么在某些原因项目将鼻子检测为嘴巴。 我有两种方法:

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;
}

并检测微笑

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");
            }
        }
    }

例子:

为了那张照片

正确检测到此安装:

但在其他图片中

检测到鼻子

您认为有什么问题?

【问题讨论】:

    标签: java opencv face-detection haar-classifier


    【解决方案1】:

    它很可能在您的照片上检测到错误,因为面部比例(与眼睛之间的距离相比,眼睛到嘴巴的距离太长)。使用haar检测器检测口鼻不是很稳定,因此算法通常使用人脸几何模型,为每个人脸特征选择最佳候选特征组合。如果没有找到候选嘴巴,一些实现甚至可以尝试根据眼睛预测嘴巴位置。

    Haar 检测器并不是目前用于特征检测的最新和最著名的检测器。尝试使用可变形零件模型实现。试试这个,他们有 matlab 代码和高效的 c++ 优化函数: https://www.ics.uci.edu/~xzhu/face/

    【讨论】:

      猜你喜欢
      • 2016-10-08
      • 2023-04-06
      • 2015-06-25
      • 2016-10-19
      • 2012-10-19
      • 2013-10-21
      • 2018-09-27
      • 2013-07-14
      • 2013-01-20
      相关资源
      最近更新 更多