Using C++ OpenCV code with Android binary package

The Android way is writing all your code in Java. But sometimes it is not enough and you need to go to the native level and write some parts of your application in C/C++. This is especially important when you already have some computer vision code which is written in C++ and uses OpenCV, and you want to reuse it in your Android application, but do not want to rewrite the C++ code to Java. In this case the only way is to use JNI - a Java framework for interaction with native code. It means, that you should add a Java class with native methods exposing your C++ functionality to the Java part of your Android application.

This tutorial describes a fast way to create and build Android applications containing OpenCV code written in C++. It shows how to build an application which uses OpenCV inside its JNI calls. Tutorial 3 and 4 from the OpenCV for Android SDK can be used as examples. OpenCV Sample “face-detect” also contain a call to C++ class.

Please note that before starting this tutorial you should fulfill all the steps, described in the tutorial Using Android binary package with Eclipse.

This tutorial was tested using Ubuntu 10.04 and Windows 7 SP1 operating systems. Nevertheless, it should also work on Mac OS X. If you encounter errors after following the steps described here, feel free to contact us via OpenCV4Android discussion group or OpenCV Q&A forum and we will try to help you.

Prerequisites: Setup Android NDK

To compile C++ code for Android platform you need Android Native Development Kit (NDK).

You can get the latest version of NDK from the download page. To install Android NDK just extract the archive to some folder on your computer. Here are installation instructions.

Note

Before start you can read official Android NDK documentation which is in the Android NDK archive, in the folder docs/.

The main article about using Android NDK build system is in the ANDROID-MK.html file.

Some additional information you can find in the APPLICATION-MK.html, NDK-BUILD.html files, and CPU-ARM-NEON.html, CPLUSPLUS-SUPPORT.html, PREBUILTS.html.

Theory: Android application structure

Usually code of an Android application has the following structure:

  • root folder of the project/
    • jni/
    • libs/
    • res/
    • src/
    • AndroidManifest.xml
    • project.properties
    • ... other files ...

where

  • the src folder contains Java code of the application,

  • the res folder contains resources of the application (images, xml files describing UI layout , etc),

  • the libs folder will contain native libraries after successful build,

  • and the jni folder contains C/C++ application source code and NDK’s build scripts Android.mk and Application.mk.

    These scripts control the C++ build process (they are written in Makefile language).

Also the root folder should contain the following files:

  • AndroidManifest.xml file presents essential information about application to the Android system (name of the Application, name of main application’s package, components of the application, required permissions, etc).

    It can be created using Eclipse wizard or android tool from Android SDK.

  • project.properties is a text file containing information about target Android platform and other build details.

    This file is generated by Eclipse or can be created with android tool from Android SDK.

Note

Both files (AndroidManifest.xml and project.properties) are required to compile the C++ part of the application (NDK build system uses information from these files). If any of these files does not exist, compile the Java part of the project before the C++ part.

Theory: Building application with C++ native part from command line

Here is the standard way to compile C++ part of an Android application:

  1. Open console and go to the root folder of Android application

    cd <root folder of the project>/
    

    Note

    Alternatively you can go to the jni folder of Android project. But samples from OpenCV binary package are configured for building from the project root level (because of relative path to the OpenCV library).

  2. Run the following command

    <path_where_NDK_is_placed>/ndk-build
    

    Note

    On Windows we recommend to use ndk-build.cmd in standard Windows console (cmd.exe) rather than the similar bash script in Cygwin shell.

    NDK build
  3. After executing this command the C++ part of the source code is compiled.

After that the Java part of the application can be (re)compiled (using either Eclipse or ant build tool).

Note

Some parameters can be set for the ndk-build:

Example 1: Verbose compilation

<path_where_NDK_is_placed>/ndk-build V=1

Example 2: Rebuild all

<path_where_NDK_is_placed>/ndk-build -B

Theory: Building application with C++ native part from Eclipse

There are several possible ways to integrate compilation of C++ code by Android NDK into Eclipse compilation process. We recommend the approach based on Eclipse CDT Builder.

Important

Make sure your Eclipse IDE has the CDT plugin installed. Menu Help -> About Eclipse SDK and push Installation Details button.

Configure builders

To install the CDT plugin use menu Help -> Install New Software..., then paste the CDT 8.0 repository URL http://download.eclipse.org/tools/cdt/releases/indigo as shown in the picture below and click Add..., name it CDT and click OK.

Configure builders

CDT Main Features should be enough:

Configure builders

Important

OpenCV for Android 2.4.2 package contains sample projects pre-configured to use CDT Builder. It automatically builds JNI part via ndk-build.

  1. Define the NDKROOT environment variable containing the path to Android NDK in your system (e.g. “X:\Apps\android-ndk-r8” or “/opt/android-ndk-r8”).

  2. CDT Builder is configured for Windows hosts, on Linux or MacOS open Project Properties of the projects having JNI part (face-detection, Tutorial 3 and Tutorial 4), select C/C++ Build in the left pane, remove ”.cmd” and leave "${NDKROOT}/ndk-build" in the Build command edit box and click OK.

    Configure CDT
  3. Use menu Project -> Clean... to make sure that NDK build is invoked on the project build:

    Select resources folder to refresh automatically

Theory: The structure of Android.mk and Application.mk scripts

The script Android.mk usually have the following structure:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := <module_name>
LOCAL_SRC_FILES := <list of .c and .cpp project files>
<some variable name> := <some variable value>
...
<some variable name> := <some variable value>

include $(BUILD_SHARED_LIBRARY)

This is the minimal file Android.mk, which builds a C++ source code of an Android application. Note that the first two lines and the last line are mandatory for any Android.mk.

Usually the file Application.mk is optional, but in case of project using OpenCV, when STL and exceptions are used in C++, it also should be written. Example of the file Application.mk:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a

Practice: Build samples from OpenCV binary package

OpenCV binary package includes 3 samples having JNI resources:

  • Tutorial 3 (Advanced) - Add Native OpenCV

    This sample illustrates how you can use OpenCV in C++ but without OpenCV Java API.

  • Tutorial 4 (Advanced) - Mix Java+Native OpenCV

    This sample shows how you can mix OpenCV Java API and native C++ code.

  • Sample - face-detection

    This sample illustrates usage of both simple OpenCV face detector via Java API and advanced detection based face tracker via JNI and C++.

Important

Before OpenCV 2.4.2 for Android these projects were not configured to use CDT for building their native part , so you can do it yourself.

Practice: Create an Android application, which uses OpenCV

To build your own Android application, which uses OpenCV from native part, the following steps should be done:

  1. The archive with OpenCV binary package should be downloaded and extracted to some folder (e.g. C:\Work\android-opencv\OpenCV-2.4.0)

  2. You can use an environment variable to specify the location of OpenCV package or just hardcode full or relative path in the jni/Android.mk of your projects.

  3. The file jni/Android.mk should be written for the current application using the common rules for the file.

    For detailed information see the Android NDK documentation from the Android NDK archive, in the file <path_where_NDK_is_placed>/docs/ANDROID-MK.html

  4. The line

    include C:\Work\android-opencv\OpenCV-2.4.0\share\OpenCV\OpenCV.mk
    

    should be inserted into the jni/Android.mk file right after the line

    include $(CLEAR_VARS)
    

    Several variables can be used to customize OpenCV stuff, they should be set before the "include ...\OpenCV.mk" line:

    OPENCV_INSTALL_MODULES:=on
    

    Copies necessary OpenCV dynamic libs to the project libs folder in order to include them into the APK.

    OPENCV_CAMERA_MODULES:=off
    

    Skip native OpenCV camera related libs copying to the project libs folder.

    OPENCV_LIB_TYPE:=STATIC
    

    Perform static link with OpenCV. By default dynamic link is used and the project JNI lib depends on libopencv_java.so.

  5. The file Application.mk should exist and should contain lines

    APP_STL := gnustl_static
    APP_CPPFLAGS := -frtti -fexceptions
    

    Also the line

    APP_ABI := armeabi-v7a
    

    is recommended for the applications targeting modern ARMs

  6. Either use manual ndk-build invocation or setup Eclipse CDT Builder to build native JNI lib before Java part [re]build and APK creation.