Use Android Studio 2.2 and Cmake (CMakeLists) to make OpenCV fly

Keywords: Android OpenCV SDK Attribute

Github project address
No response to any questions about "how to configure"
2017-01-13: Updated to OpenCV3.2

If you're too lazy to match it yourself, you can download it directly, including OpenCV 3.x for Android (Java and NDK C++, no additional configuration, no OpenCV Manager), which uses Cmake as a tool, and provide a simple camera Preview demo (note that it only contains armeabi-v7a, if you need other types, you can refer to the tutorial itself). Line configuration)

It takes about 10 minutes to configure according to this tutorial.

Explain

Since the release of Android Studio 2.2 stable version, support for NDK has become better than before (finally support Cmake, moving), but the most common way to use OpenCV on Android is to use Android.mk+ndk_build or use gradle-experiment.

target

  • Use Cmake to compile OpenCV 3.1 for Android, leaving Android.mk aside (in theory, this method can also be used for OpenCV 2.4X)
  • It also supports the compilation of OpenCV and NDK (C++) in Java layer, and has code hints and completions.
  • Remove OpenCV Manager

1. pre preparation

This part is quoted from Here

  • Make sure your Android Studio version has been upgraded to 2.2 and above
  • Download ndk and download the corresponding ndk at File - > Settings - > Appearance & Behavior - > System Settings - > Android SDK
  • Download CMAKE,LLDB from the same location

2. OpenCV support for Java

  • Create a new project, check C++ support
  • Importing the Java folder under OpenCV (path OpenCV-android-sdk\sdk\java) as a module may require modifications to gradle and minSDK versions

  • Adding dependencies on OpenCV Library to the main module

  • Now that OpenCV's Java layer configuration is complete, sync, there should be code completion
  • To use OpenCV Library happily, you can add the following permissions directly to Android Manifest. XML
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>

<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3. OpenCV support for NDK/native (C++)

  • Copy the include folder (path OpenCV-android-sdk sdk native jni include) into the CPP folder (path app src main cpp)
  • Copy the dependent dynamic and static libraries (path is OpenCV-android-sdk\sdk\nativelibs) under\srcmainjniLibs
  • To complete the above steps, your engineering structure should be the same as the figure below.

  • Modify the gradle of app, because we have introduced C++ support before, so change it directly to this (see the full gradle project)

externalNativeBuild {
    cmake {
        //arguments  '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
        cppFlags "-std=c++11","-frtti", "-fexceptions"
    }
}
ndk{
    abiFilters 'armeabi-v7a'
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • Modifying CMakeLists is an important step

The main function of CMakeLists is to tell NDK what my source code is, which header files to include, what my third-party dependency libraries are, and how to compile them.

The information provided here is for reference only (add all. so and. a directly)

cmake_minimum_required(VERSION 3.6)

set(CMAKE_VERBOSE_MAKEFILE on)
set(libs "${CMAKE_SOURCE_DIR}/src/main/jniLibs")
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)

add_library(libopencv_java3 SHARED IMPORTED )
set_target_properties(libopencv_java3 PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_java3.so")

add_library(libopencv_java SHARED IMPORTED )
set_target_properties(libopencv_java PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_java.so")

add_library(libopencv_calib3d STATIC IMPORTED )
set_target_properties(libopencv_calib3d PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_calib3d.a")

add_library(libopencv_core STATIC IMPORTED )
set_target_properties(libopencv_core PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_core.a")

add_library(libopencv_features2d STATIC IMPORTED )
set_target_properties(libopencv_features2d PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_features2d.a")

add_library(libopencv_flann STATIC IMPORTED )
set_target_properties(libopencv_flann PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_flann.a")

add_library(libopencv_highgui STATIC IMPORTED )
set_target_properties(libopencv_highgui PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_highgui.a")

add_library(libopencv_imgcodecs STATIC IMPORTED )
set_target_properties(libopencv_imgcodecs PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_imgcodecs.a")

add_library(libopencv_imgproc STATIC IMPORTED )
set_target_properties(libopencv_imgproc PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_imgproc.a")

add_library(libopencv_ml STATIC IMPORTED )
set_target_properties(libopencv_ml PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_ml.a")

add_library(libopencv_objdetect STATIC IMPORTED )
set_target_properties(libopencv_objdetect PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_objdetect.a")

add_library(libopencv_photo STATIC IMPORTED )
set_target_properties(libopencv_photo PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_photo.a")

add_library(libopencv_shape STATIC IMPORTED )
set_target_properties(libopencv_shape PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_shape.a")

add_library(libopencv_stitching STATIC IMPORTED )
set_target_properties(libopencv_stitching PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_stitching.a")

add_library(libopencv_superres STATIC IMPORTED )
set_target_properties(libopencv_superres PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_superres.a")

add_library(libopencv_video STATIC IMPORTED )
set_target_properties(libopencv_video PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_video.a")

add_library(libopencv_videoio STATIC IMPORTED )
set_target_properties(libopencv_videoio PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_videoio.a")

add_library(libopencv_videostab STATIC IMPORTED )
set_target_properties(libopencv_videostab PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_videostab.a")

add_library(libopencv_ts STATIC IMPORTED )
set_target_properties(libopencv_ts PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_ts.a")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fexceptions -frtti")


#include_directories(D:/Projects/Android/CLMAndroid/OpenCV-android-sdk/sdk/native/jni/include )
#set(OpenCV_DIR D:/Projects/Android/CLMAndroid/OpenCV-android-sdk/sdk/native/jni)
#find_package(OpenCV REQUIRED)
#target_link_libraries(${OpenCV_LIBS})

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             # Associated headers in the same location as their source
             # file are automatically included.
             src/main/cpp/native-lib.cpp )

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log)

target_link_libraries(native-lib android log
    libopencv_java3 libopencv_java libopencv_calib3d libopencv_core libopencv_features2d libopencv_flann libopencv_highgui libopencv_imgcodecs
    libopencv_imgproc libopencv_ml libopencv_objdetect libopencv_photo libopencv_shape libopencv_stitching libopencv_superres
    libopencv_video libopencv_videoio libopencv_videostab
    ${log-lib}
    )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

Synchronization or rebuild, there should have been code completion, C++ layer configuration so far, is it very convenient?

Remove OpenCV Manager

OpenCV Manager's role is to provide some common dynamic link libraries, but it's really annoying to install an additional Apk.

  • The dynamic link libraries in OpenCV Manager have these main features. Let's copy the last two to jniLibs (native_camera is supposed to open the camera for C++ layer, because the camera Preview is usually in Java layer, so you can not add them. If you have problems with the camera, you can try adding them.)

  • Because of the removal of OpenCV Manager, we have to load the class library ourselves, pay attention to the order of loading, native-lib is just the result of our own cpp compilation.

static {
    System.loadLibrary("opencv_java3");
    System.loadLibrary("opencv_java");
    System.loadLibrary("native-lib");
}
  • 1
  • 2
  • 3
  • 4
  • 5

In this way, we successfully removed OpenCV Manager

About so file location

In this project, jniLibs is a folder associated with MakeLists, which will be automatically packaged into the APK of this Module in the latest AS version. If it is not packaged, you can try to modify the lib path to the specified path.

sourceSets.main {
        jniLibs.srcDirs = ['libs']
        jni.srcDirs = []
}
  • 1
  • 2
  • 3
  • 4

This is the end of the tutorial. Enjoy using Cmake and let your OpenCV fly.

For demo(demo is sample2, used for camera preview and feature detection), please check in the project. I have slightly modified the Java class library and added a touch focus camera.

Github project address

Posted by bhogg on Mon, 10 Dec 2018 00:03:05 -0800