如何使用JavaCV在Android中加载ClassifierCascade?

时间:2013-03-26 16:33:55

标签: opencv javacv

我正在尝试使用Android进行面部识别。所有负载都可以,但是 haarcascade_frontalface_alt2.xml 文件,我不知道如何使用JavaCV加载它。 这是我的代码:

public static void detectFacialFeatures()
{
    // The cascade definition to be used for detection.

    // This will redirect the OpenCV errors to the Java console to give you
    // feedback about any problems that may occur.
    new JavaCvErrorCallback();

    // Load the original image.

    // We need a grayscale image in order to do the recognition, so we
    // create a new image of the same size as the original one.
    IplImage grayImage = IplImage.create(iplImage.width(),iplImage.height(), IPL_DEPTH_8U, 1);

    // We convert the original image to grayscale.
    cvCvtColor(iplImage, grayImage, CV_BGR2GRAY);

    CvMemStorage storage = CvMemStorage.create();

    // We instantiate a classifier cascade to be used for detection, using the cascade definition.
    CvHaarClassifierCascade cascade = new CvHaarClassifierCascade(cvLoad("./haarcascade_frontalface_alt2.xml"));

    // We detect the faces.
    CvSeq faces = cvHaarDetectObjects(grayImage, cascade, storage, 1.1, 1, 0);

    Log.d("CARAS","Hay "+faces.total()+" caras ahora mismo");
}

问题出在这里

  

CvHaarClassifierCascade(cvLoad( “./ haarcascade_frontalface_alt2.xml”));

我已经尝试将xml文件放入/ assets文件夹,但我不知道如何加载它。它总是给我下一个错误:

03-26 17:31:25.385: E/cv::error()(14787): OpenCV Error: Null pointer (Invalid classifier cascade) in CvSeq* cvHaarDetectObjectsForROC(const CvArr*, CvHaarClassifierCascade*, CvMemStorage*, std::vector<int>&, std::vector<double>&, double, int, int, CvSize, CvSize, bool), file /home/saudet/projects/cppjars/OpenCV-2.4.4/modules/objdetect/src/haar.cpp, line 1514

... 看起来更接近它指向此代码行的错误:

  

CvSeq faces = cvHaarDetectObjects(grayImage,cascade,storage,1.1,1,   0);

这就是我很确定问题来自haarcascade_frontalface_alt2.xml加载的原因。

感谢您的帮助。

P.D:我想将级联包含在apk中而不是sdcard中。

2 个答案:

答案 0 :(得分:0)

如果您的级联在SD卡中,您可以使用:

CascadeClassifier cascade = new CascadeClassifier(Environment.getExternalStorageDirectory().getAbsolutePath() + "/cascade.xml");

Environment.getExternalStorageDirectory().getAbsolutePath()为您提供正确的SD卡路径,然后是SD卡中的文件地址。

答案 1 :(得分:0)

您可以将文件打包到apk中,然后将其复制到外部位置,以便OpenCV函数可以访问它。

    try {
        File learnedInputFile = new File(Environment.getExternalStorageDirectory().getPath() + "/learnedData.xml");
        if (!learnedInputFile.exists()) {
            InputStream learnedDataInputStream = assetManager.open("learnedData.xml");
            FileOutputStream learnedDataOutputStream = new FileOutputStream(learnedInputFile);

            // copy file from asset folder to external location, i.e. sdcard
            byte[] buffer = new byte[300];
            int n = 0;
            while (-1 != (n = learnedDataInputStream.read(buffer))) {
                learnedDataOutputStream.write(buffer, 0, n);
            }
        }
        classifier.load(learnedInputFile.getAbsolutePath());
    } catch (IOException exception) {
        // there are no learned data, train ml algorithm or show error, etc.
    }