【问题标题】:OpenCV Java Smile DetectionOpenCV Java 微笑检测
【发布时间】:2015-02-16 23:24:10
【问题描述】:

我尝试使用在 Internet 上找到的源代码创建一个微笑检测器。它可以检测面部并且效果很好。它使用 Haar 分类器,我找到了用于微笑识别的 Haar 分类器并尝试了它,但是它不起作用。我尝试以与识别面部相同的方式使用它。用眼睛分类器尝试了同样的方法——它奏效了。我在 opencv/data 文件夹中找到的所有分类器,有人可以给我一个提示,我可以用给定的代码做更多的事情吗?

import java.io.File;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.objdetect.CascadeClassifier;

public class SmileDetector {

public void detectSmile(String filename) {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    System.out.println("\nRunning SmileDetector");

    CascadeClassifier faceDetector = new CascadeClassifier(new File(
            "src/main/resources/haarcascade_frontalface_alt.xml").getAbsolutePath());
    CascadeClassifier smileDetector = new CascadeClassifier(
            new File("src/main/resources/haarcascade_smile.xml").getAbsolutePath());
    Mat image = Highgui.imread(filename);
    MatOfRect faceDetections = new MatOfRect();
    MatOfRect smileDetections = new MatOfRect();
    faceDetector.detectMultiScale(image, faceDetections);

    System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

    for (Rect rect : faceDetections.toArray()) {
        Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
                new Scalar(0, 255, 0));
    }
    Mat face = image.submat(faceDetections.toArray()[0]);
    smileDetector.detectMultiScale(face, smileDetections);

    for (Rect rect : smileDetections.toArray()) {
        Core.rectangle(face, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
                new Scalar(0, 255, 0));
    }

    String outputFilename = "ouput.png";
    System.out.println(String.format("Writing %s", outputFilename));
    Highgui.imwrite(outputFilename, image);
    Highgui.imwrite("ee.png", face);
}
}

【问题讨论】:

  • 您好,我也在尝试做同样的事情,您找到解决问题的方法了吗?
  • 还没有,等我在家的时候,我会尝试使用 haar 级联来解决这个问题,因为我相信问题出在那儿。
  • 这个帖子有什么更新吗?
  • 不行,我试过把鬼王的代码翻译成java,但是没有成功
  • 在哪里可以解决您的问题?解决方案是什么?

标签: java opencv


【解决方案1】:

回答 Vi Matviichuk 评论: 是的,我能够部分解决问题。我使用了嘴巴分类器而不是微笑,opencv 样本中嘴巴分类器的名称是 haarcascade_mcs_mouth.xml ;然后你寻找面孔,裁剪它们并在面孔上寻找嘴巴。但是它会给你很多嘴,所以你必须通过以下方式过滤它们:

/**
 * Detects face(s) and then for each detects and crops mouth
 * 
 * @param filename path to file on which smile(s) will be detected
 * @return List of Mat objects with cropped mouth pictures.
 */
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;
}

那你必须找到一个微笑,我尝试用 SVM 训练机来做这个,但是我没有足够的样本所以它并不完美。但是,我得到的全部代码可以在这里找到:https://bitbucket.org/cybuch/smile-detector/src/ac8a309454c3467ffd8bc1c34ad95879cb059328/src/main/java/org/cybuch/smiledetector/SmileDetector.java?at=master

【讨论】:

  • 我需要你的帮助,我也在研究 OpenCV,我在哪里可以获得一些培训文件?我需要创建它们吗?如果是这样,如何? (你有博客或其他东西的链接)提前谢谢。
  • AFAIR 你需要你自己的训练文件,但是如果你正在检测微笑,我想有一个 Haar 分类器可以很好地使用它
猜你喜欢
  • 2011-08-17
  • 2016-06-02
  • 2020-09-14
  • 1970-01-01
  • 2013-10-30
  • 2020-08-16
  • 2012-10-09
  • 2016-10-17
  • 1970-01-01
相关资源
最近更新 更多