There are several tutorials on how to make OpenCV work on Android but, apparently, it’s not as straightforward as it seems. This tutorial shows how to make the samples provided with the OpenCV
Android SDK work under AndroidStudio 2.2.3, in particular the second sample “tutorial-2-mixedprocessing”.


I assume that you have a working installation of AndroidStudio 2.2.3. All the commands presented in the following are run on Ubuntu Linux 16.04. In shell code samples the prompt is denoted by $.

Getting the OpenCV SDK

The latest OpenCV stable release at the time of writing is 3.2.0. You can get the Android SDK
here.

Once you have downloaded the distribution you can unzip it.

$ cd ~/Downloads/
$ unzip opencv-3.2.0-android-sdk.zip

This will create a directory ~/Downloads/OpenCV-android-sdk which contains the components we will use in the next steps. In what follows, I will refer to this directory with $OPENCV_SDK.

Setting up a project

Open AndroidStudio and create a new project, say TestOpenCV, accepting all the defaults. We will re-configure it later. By default, AndroidStudio creates a project consisting of a root module and a
single subproject named app.

Now we need to make our new project depend on OpenCV’s Android SDK which, unfortunately, is not “gradle-ready”, since it’s and Eclipse project. To work around this problem we will create a new
subproject in TestOpenCV which will host OpenCV’s SDK.

First of all, we need to import the relevant code. In the directory of TestOpenCV issue the following commands

$ mkdir -p opencv-sdk/src/main
$ cp -r $OPENCV_SDK/sdk/java/src/ opencv-sdk/src/main/java
$ cp -r $OPENCV_SDK/sdk/java/res opencv-sdk/src/main/res
$ cp $OPENCV_SDK/sdk/java/AndroidManifest.xml opencv-sdk/src/main/
$ mkdir -p opencv-sdk/src/main/aidl/org/opencv/engine/
$ mv opencv-sdk/src/main/java/org/opencv/engine/OpenCVEngineInterface.aidl opencv-sdk/src/main/aidl/org/opencv/engine

Then create a file opencv-sdk/build.gradle with the following content (matching the target and minimum sdk versions to the ones configured in app/build.gradle)

apply plugin: 'com.android.library'

android {
    compileSdkVersion 22
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 22
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

Then, we can add the opencv-sdk subproject to our gradle build by modifying the content of settings.gradle to look like the following

include ':app', ':opencv-sdk'

Finally, we can make our subproject app on opencv-sdk by modifying app/build.gradle so that the dependencies section looks like the following

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:22.2.1'
    testCompile 'junit:junit:4.12'

    compile project(':opencv-sdk')
}

note the last line, which is where we actually set up the dependency.

Including shared libraries

Now we need to add to our app module the native libraries that will be shipped with our application. In order to do so, issue the following commands

$ cp -r $OPENCV_SDK/sdk/native/libs/ app/src/main/jniLibs

Importing the sample’s code

Now we are ready to include the code of the sample tutorial-2-mixedprocessing.

$ rm -r app/src/main/java app/src/main/res app/src/main/AndroidManifest.xml
$ cp $OPENCV_SDK/samples/tutorial-2-mixedprocessing/AndroidManifest.xml app/src/main
$ cp -r $OPENCV_SDK/samples/tutorial-2-mixedprocessing/src app/src/main/java
$ cp -r $OPENCV_SDK/samples/tutorial-2-mixedprocessing/jni app/src/main/jni
$ cp -r $OPENCV_SDK/samples/tutorial-2-mixedprocessing/res app/src/main/res

Set up additional tools

In order to compile native code, we need to configure AndroidStudio properly by installing the appropriate tools. Open Tools > Android > SDK Manager, go to SDK Tools and install LLDB, Cmake, and NDK.

Building native code

Everything is almost ready, we just need to tell Gradle how to compile our native code, specifically the one in the app/src/main/jni directory. OpenCV developers already provided us with an Android.mk and Application.mk. We just have to tweak them a little and point Gradle to them.

Modify app/src/main/jni/Android.mk so that its contents look like

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include /home/ceccarel/Scaricati/OpenCV-android-sdk/sdk/native/jni/OpenCV.mk

LOCAL_MODULE    := mixed_sample
LOCAL_SRC_FILES := jni_part.cpp
LOCAL_LDLIBS +=  -llog -ldl

include $(BUILD_SHARED_LIBRARY)

replacing /home/ceccarel/Scaricati/OpenCV-android-sdk with the actual path to the directory $OPENCV_SDK on your system.

Then, modify app/build.gradle so that it looks like

// ... elided ...

android {
    // ... elided ....

    externalNativeBuild {
        ndkBuild {
            path 'src/main/jni/Android.mk'
        }
    }
}

// ... elided ...

This last step tells Gradle to build native code from our src/main/jni directory during the build process.


Now everything is set up and ready, and you can compile and run the project.