【问题标题】:How to load ClassifierCascade in Android using JavaCV?如何使用 JavaCV 在 Android 中加载 ClassifierCascade?
【发布时间】:2013-04-10 00:20:53
【问题描述】:

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

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 中。

【问题讨论】:

    标签: opencv javacv


    【解决方案1】:

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

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

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

    【讨论】:

    • 抱歉,我正在等待包含在 apk 级联文件中。
    • 我遇到了同样的问题。但仍然不知道该怎么做。我尝试从 file:///android_asset/cascade.xmlalso this 之类的资产中读取,但没有成功。也许它是特定于设备的,在某些设备中它会起作用。我认为方法是-将xml从资产写入SD,读取并删除后。或许在未来会是最好的方式。
    【解决方案2】:

    您可以将文件打包在 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.
        }
    

    【讨论】:

    • 这实际上不是 JavaCV,而是 OpenCV 的官方 java api 绑定,但在你的情况下 CvLoad 应该可以代替我的 CvStatModel::load() 函数工作。
    猜你喜欢
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 2012-11-25
    • 2023-03-13
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多