0

I'm testing the creation of the Android apps integrating C++ code. In this example I'm using the OpenCV library

I setup the environment and I was also able to compile and deploy. The app works correctly. Beautiful until here. There is a little UX problem though. The app makes use of two xml files:

haarcascade_frontalface_alt.xml
haarcascade_eye_tree_eyeglasses.xml

but at the moment the final user needs to post-download them on device and in a given folder, otherwise the app would be unable to perform the respective detections. The significant part of code so far is the following:

JNIEXPORT void JNICALL Java_com_demo_test_opencvsample_OpenCVClass_faceDetection
  (JNIEnv *, jclass, jlong addrRgba){
    Mat& frame = *(Mat*)addrRgba;

    detect(frame);
}

void detect(Mat& frame){
    // these files will be loaded from a specific folder in the phone memory
    String face_cascade_name = "/storage/emulated/0/data/haarcascade_frontalface_alt.xml";
    String eyes_cascade_name = "/storage/emulated/0/data/haarcascade_eye_tree_eyeglasses.xml";
    CascadeClassifier face_cascade;
    CascadeClassifier eyes_cascade;

    //-- 1. Load the cascades
    if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return; };
    if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return; };


-> question: is there a way to integrate the two xml files directly in the apk avoiding a final user to have to download them separately on his device after the installation of the app? I would like him to have them directly available after the app gets installed and the C++ code, also because they are not supposed to be changed

NOTE before answering: I'm not interested in putting two download buttons in the final app and not even in having a full-android solution. I would like to maintain the current architecture making use of the C++ core

Thanks in advance to those who will try to help

Antonino
  • 3,178
  • 3
  • 24
  • 39
  • Have you considered using assets? (https://coderwall.com/p/0ldbgw/working-with-assets-in-android) – VolAnd Jul 10 '17 at 06:10
  • ciao @VolAnd, thanks for your answer! I was checking the answer for Steve which is a little bit more complete. I had read about Assets folder and it's kinda plain handling that with a pure Android approach, I saw also this article which was very good: http://www.41post.com/3985/programming/android-loading-files-from-the-assets-and-raw-folders but - once moved in the Assets folder - the problem is being able to access these files through the C++ code. Have a good day! – Antonino Jul 13 '17 at 02:14

1 Answers1

1

The Asset API is mentioned as available in android NDK levels which forwards to this page android ndk asset_manager.h

In here it describes a set of APIs which are fopen like, which allow bundled assets to be opened.

Hard-coding paths is not the correct way to manage your files, as different devices, or future/past operating systems may rearrange the file system.

SO : How to get ExternalDirectory in NDK shows how in general to call android functions from NDK, and specifically how to load the externalDirectory - the root directory of the sdcard (user visible when a device is attached to a computer.

For files which are only related to your project (which seems to be the case here), I would recommend storing the xml files in the application directory, which can be accessed through jni from Context->getFilesDir() (see android : Context

  1. If your xml files are static, and unlikely to change more frequently than your application, use assets.
  2. If your xml files will be updated by the application, or yourself, use the getFilesDir()
  3. If you want your uses to see the XML files, (and be able to edit them?) then use getExternalDirectory()
mksteve
  • 12,614
  • 3
  • 28
  • 50
  • ciao @mksteve, I read your linked docs and thanks a lot for your time. I'm not yet clear on how to proceed under the coding point of view. I put the two xml files into the Assets folder. My idea now would be something close to call from C++ something which basically means face_cascade.load("app/src/main/Assets/haarcascade_frontalface_alt.xml"). So to grab from android your proposal is to change the original OpenCV load function [https://github.com/opencv/opencv/blob/master/apps/traincascade/cascadeclassifier.cpp] with calls like AAsset_openFileDescriptor()? do you know/have any example? – Antonino Jul 13 '17 at 02:04