3

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

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

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

4

1 回答 1

6

我对 Android 还很陌生,但我认为正确的答案是,严格意义上来说,你真的不能。尽管如此,以下内容可能不如您(和我)预期的那么好,我在这里找到了 Pietmau 的以下解决方法。基本上,正如您所希望的,将您的 xml 放在 resource/raw 目录中,然后在您的代码中读取它,将其保存到外部文件中,然后通过传递该文件的路径将其加载到分类器中。是的,我知道...

该方法将是:

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

那好吧...

于 2013-12-26T16:04:45.690 回答