Building OpenCV for Android and using it with the NDK

后端 未结 1 1609
醉酒成梦
醉酒成梦 2020-12-14 05:05

Context : I am currently developing an app on Android Studio for the Moverio BT 200 augmented reality glasses. I am using OpenCV, and specifically, the arUco module of the l

相关标签:
1条回答
  • 2020-12-14 05:48

    So the mips architecture problem can be solved by adding the following code to the gradle.build of app, at the end of the android block :

    productFlavors {
        armv7 {
            ndk {
                abiFilter "armeabi-v7a"
            }
        }
        fat
    }
    

    But then, other problems arised. Notably, the library is built with the carotene options, which Android Studio doesn't like, and then, the gzlib misses, so Android Studio can't build and / or run. So after MANY trials, I finally achieved what I wanted : cross-compilation of openCV with extra modules for Android on Windows, and building an AS project with said built library so that it works. I documented my whole proccess, from downloading the openCV sources up until running my application on my arm-architected device, I'll just copy paste it here for anyone who needs to do that too. The following instructions are mainly based on this tutorial (thank you to Zamrath Nizam who wrote it). The only problem with that tutorial is that it's probably a little old, so some options / steps need to be altered.

    CROSS COMPILE OPENCV FROM SOURCE WITH EXTRA MODULES FOR ANDROID FROM WINDOWS10

    * FIRST : prerequisites *

    • download OpenCV and unzip (say at '../opencv-source')
    • download OpenCV extra modules and unzip (say at '../opencv-contrib-source')
    • download Android NDK (say at '../ndk-dir')
    • download CMake (to say '../cmake-dir') and MinGW (to say '../mingw-dir')
    • install Android Studio

    * SECOND : configure with CMake *

    • go to '../opencv-source/platforms' and create a folder named 'build_android_arm'
    • in CMake, fill the following first two fields with the following paths :
      1. where is the source code : '../opencv-source'
      2. where to build the binaries : '../opencv-source/platforms/build_android_arm'
    • add the following options via the 'Add Entry' :
      1. ANDROID_NDK, type 'path', value '../ndk-dir'
      2. ANDROID_NDK_HOST_X64, type 'bool', value 1
      3. CMAKE_TOOLCHAIN_FILE, type 'path', value '../opencv-source/platforms/android/android.toolchain.cmake'
    • press 'Configure'
    • choose 'MinGW Makefiles' as the compiler
    • choose 'Specify toolchain file for cross-compiling'
    • press 'Next', and 'Finish'
      • note 1 : As long as you've got no error message, everything's good. Don't worry about the warning messages (like CMake telling you you're doing deprecated stuff).
      • note 2 : If you can't configure at that step, try to read the next few points, it might help.
    • change the following additional options via the 'Search' field :

      1. EXTRA_MODULE_PATH, type 'path', value '../opencv-contrib-source/modules'
      2. WITH_CAROTENE, type 'bool', value 0
      3. BUILD_ZLIB, type 'bool', value 1
        • note : You MUST have configured already once before this step, because the variables created before are regrouped under the group 'Ungrouped entries', while the following variables are CMake automatically generated variables, and NEED to be grouped in the right groups (which is NOT 'Ungrouped entries').
    • verify that the following options are correctly set up (via the 'Search' field) :

      1. ANDROID_NDK_HOST_X64, type 'bool', value 1
      2. CMAKE_MAKE_PROGRAM, type 'path', value '../mingw-dir/bin/mingw32-make.exe'. This option, I actually DIDN'T have it in my CMake config. IF when you press 'Configure', it doesn't work AND you don't have this option, then you should try adding it (but I don't know how). IF when you press 'Configure' you don't have any problem, don't bother about that variable. This check comes from the original tutorial linked above.
      3. CMAKE_TOOLCHAIN_FILE, type 'path', value '../opencv-source/platforms/android/android.toolchain.cmake'
    • press 'Configure'

    • choose 'MinGW Makefiles' as the compiler
    • choose 'Specify toolchain file for cross-compiling'
    • press 'Next', and 'Finish'
    • press 'Generate'

    * THIRD : compile with mingw *

    • go to '../mingw-dir/msys/1.0' and run 'msys' bash file
    • navigate to '../opencv-source/platforms/android_arm'
    • run 'mingw32-make' command
    • run 'mingw32-make install' command

    * FOURTH : android project *

    • launch Android Studio and create a new project :
      1. select File -> New -> New Project...
      2. fill the 'Application name' with let's say 'cOCV'
      3. check the 'Include C++ Support' box
      4. click 'Next'
      5. choose your min SDK (let's say API 14: Android 4.0 (IceCreamSandwich)
      6. click 'Next', 'Next' and 'Finish'
    • go to File -> New -> Import Module...

      1. provide '../opencv-source/platforms/android_arm/install/sdk/java'
      2. click 'Next' and 'Finish'
    • change the targets in build.gradle file in openCVLibraryXXX (imported module) folder :

      1. compileSdkVersion and targetSdkVersion should be the same, greater or equal to 23
      2. minSdkVersioon should be the same as the one specified when creating the project
    • in the build.gradle file in openCVLibraryXXX (imported module) folder :

      1. replace 'apply plugin: com.android.application' as, 'apply plugin: com.android.library'
      2. remove the line 'applicationId "org.opencv"'
        • note : That last step is done in order to avoid following error : 'unspecified on project app resolves to an APK archive which is not supported as a compilation dependency'.
    • add the imported library as a dependency to the 'app' module in File->'Project Structure'

    • create a jniLibs folder in 'app/src/main' :

      1. right click 'app' in the Android view on the left menu
      2. click 'New-Folder-JNI Folder'
      3. check the 'Change Folder Location'
      4. set the 'Target Source Set as 'app/src/main/jniLibs'
    • copy libraries of OpenCV from 'opencv-source/platforms/android_arm/install/sdk/native/libs' into the newly created folder (jniLibs) inside the 'AndroidStudioProjects/cOCV/app/src/main/jniLibs' folder

      • note : For example, my AndroidStudioProjects folder is located at 'C:\Users\JambonSama\AndroidStudioProjects'.
    • in 'opencv-contrib-source/modules/module_you_desperately_need/CMakeLists.txt', change 'ocv_define_module(module_you_desperately_need opencv some other modules)' for 'ocv_define_module(module_you_desperately_need opencv some other modules WRAP java)'

      • note 1 : THIS STEP MAY BE USELESS, because WRAP java is probably already written in the file.
      • note 2 : If 'python' is written too, it's fine, you let it be written where it is.
    • in CMakeLists.txt, add :

      1. the following two lines after the 'add_library' block and before the 'find_library' block :

         include_directories(../opencv_src/opencv/platforms/build_android_armn/install/sdk/native/jni/include)
         link_directories(../AndroidStudioProjects/cOCVn/app/src/main/jniLibs/armeabi-v7a)
        
        • note : These two lines pretty straight-forwardly give the paths for the include and link directories
      2. the following lines after the 'find_library' block and before the 'target_link_libraries' block :

         file(GLOB PARTYLIBS "../opencv_src/opencv/platforms/build_android_armn/install/sdk/native/3rdparty/libs/armeabi-v7a/*.a")
         file(GLOB CVLIBS  "../opencv_src/opencv/platforms/build_android_armn/install/sdk/native/libs/armeabi-v7a/*.a")
        
        • note : These are for easier linking commands, see next point.
      3. the following paths, AS WRITTEN, in the 'target_link_libraries', after the 'native-lib' variable, and before the '${log-lib}' one :

         ${CVLIBS}
         ${PARTYLIBS}
         ${CVLIBS}
        
        • note : THAT IS THE TRICKY PART : because of cyclical dependencies, you have to write CVLIBS, PARTYLIBS, and then CVLIBS a second time, otherwise you won't stop having linking errors. By now, everything should be linked.
    • in the gradle.build of app, add the following code :

           productFlavors {
               armv7 {
                   ndk {
                       abiFilter "armeabi-v7a"
                   }
               }
               fat
          }
      

      at the end of the android block

      • note : This prevents the mips64 architecture error at build, by specifying once and for all the arm architecture
    • in the native-lib.cpp :

      1. try the following code in the 'stringFromJNI' function (this one is automatically generated by AS when the project is created)

         cv::Mat test;
         cv::VideoCapture camera;
         camera.open(0);
         cv::Ptrcv::aruco::Dictionary dict = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
         cv::Mat marker;
         cv::aruco::drawMarker(dict, 25, 200, marker, 1);
         std::string hello = "Hello from C++";
         return env-NewStringUTF(hello.c_str());
        
      2. don't forget the following includes :

         #include jni.h
         #include string
         #include opencv2/aruco.hpp
         #include opencv2/videoio.hpp
        
        • note : Because the string is not generated before the end of the function, you know, when you test, that if the string is indeed displayed on screen, the function has been gone through without problem, and that you're good (since the above provided code use some modules that are not on the stable realease as of 08/12/2016 (8th of december, I write dates with a dd/mm/yyyy format).
    • time to test :

      1. sync the gradle
      2. build
      3. run on an arm device

    You're good to go \ o \\ O // o /

    Additional notes :

    • All the gradle.build files and the CMakeLists.txt file can be easily found on the Android View in the menu on the left of the window in AS.
    • Remember if you've got errors navigating in the command window that maybe your '/' should be '\' or the other way round. ('cd' command to navigate in a command window).
    • I run on Windows10.
    • If you're not quite sure what you should see on screen steps by steps, the tutorial I mentioned at the beginning of the answer should give you a good idea what you're supposed to see up until the AS project creation. Then, you can give a look at this tutorial, which explains how to setup OpenCV SDK in Android Studio project FOR THE OFFICIAL RELEASE. The steps I provided differs from BOTH those tutorials, but I put them here, because they can help you know what your screen / windows should look like.
    0 讨论(0)
提交回复
热议问题