是否可以从资源加载CascadeClassifier .xml文件

时间:2013-06-19 10:46:40

标签: android opencv

您可能知道CascadeClassifier::load函数需要.xml文件的路径。所以像这样的代码是合理的(在Android上):

CascadeClassifier face_cascade;
face_cascade.load( "/sdcard/haarcascade_frontalface_alt2.xml");

但我想从资源中加载它们(来自Native Part)。可能吗?在本机部分加载xml文件的最佳方法是什么? .xml文件的最佳位置在哪里?

1 个答案:

答案 0 :(得分:5)

我对Android很新,但我认为正确的答案是,从严格意义上说,你真的不能。然而,以下可能不如你(和我)期待的那样好,我从Pietmau here找到了以下解决方法。基本上,正如您所希望的那样,将您的xml放在资源/原始目录中,然后在您的代码中读取它,将其保存到外部文件,并通过传递该文件的路径将其加载到分类器中。是的,我知道......

方法是:

public void load_cascade(){
    try {
        InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);
        File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
        File mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
        FileOutputStream os = new FileOutputStream(mCascadeFile);

        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = is.read(buffer)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        is.close();
        os.close();

        face_cascade = new CascadeClassifier(mCascadeFile.getAbsolutePath());
        if(face_cascade.empty())
        {
            Log.v("MyActivity","--(!)Error loading A\n");
            return;
        }
        else
        {
            Log.v("MyActivity",
                    "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath());
        }
    } catch (IOException e) {
        e.printStackTrace();
        Log.v("MyActivity", "Failed to load cascade. Exception thrown: " + e);
    }
}

您只需在BaseLoaderCallback中加载OpenCV库后调用它:

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();
                mOpenCvCameraView.setOnTouchListener(Tutorial3Activity.this);
                load_cascade();
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

哦,好吧......